package com.neouton.crm.pm.service.impl;

import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.neouton.common.entity.ActivitiVO;
import com.neouton.common.entity.FeeMainVO;
import com.neouton.common.util.*;
import com.neouton.crm.approval.entity.ApprovalVO;
import com.neouton.crm.approval.mapper.ApprovalMapper;
import com.neouton.crm.approval.service.IApprovalService;
import com.neouton.crm.cm.entity.SalesCostMigrateVO;
import com.neouton.crm.cm.mapper.SalesCostMigrateMapper;
import com.neouton.crm.dictionary.entity.DictionaryLookupItemVO;
import com.neouton.crm.dictionary.service.IDictionaryService;
import com.neouton.crm.entity.FileUploadRecordVO;
import com.neouton.crm.entity.SysUserEntity;
import com.neouton.crm.op.entity.SalesOpportunityVO;
import com.neouton.crm.op.mapper.SalesOpportunityMapper;
import com.neouton.crm.op.service.SalesOpportunityService;
import com.neouton.crm.payRecords.entity.PaymentRecords;
import com.neouton.crm.payRecords.entity.PaymentRequest;
import com.neouton.crm.payRecords.mapper.PaymentRecordsMapper;
import com.neouton.crm.payRecords.mapper.PaymentRequestMapper;
import com.neouton.crm.paymentPlan.entity.PaymentPlan;
import com.neouton.crm.paymentPlan.mapper.PaymentPlanMapper;
import com.neouton.crm.pm.entity.*;
import com.neouton.crm.pm.mapper.*;
import com.neouton.crm.pm.service.*;
import com.neouton.crm.prm.entity.ProjectReturnedMoneyVO;
import com.neouton.crm.prm.mapper.ProjectReturnedMoneyMapper;
import com.neouton.crm.receiptRecords.entity.ReceiptRecords;
import com.neouton.crm.receiptRecords.mapper.ReceiptRecordsMapper;
import com.neouton.crm.refundRecords.entity.RefundRecordsVO;
import com.neouton.crm.refundRecords.mapper.RefundRecordsMapper;
import com.neouton.crm.sales.entity.*;
import com.neouton.crm.sales.mapper.*;
import com.neouton.crm.transpondEmail.service.TranspondEmailService;
import com.neouton.feginClient.FeginService;
import com.neouton.feginClient.ReimburseService;
import com.neouton.feginClient.WorkFlowFeginService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * @author TheSail
 * @date 2022/11/09 14:06:50
 * @description
 */
@Service
public class SalesProjectManageServiceImpl implements SalesProjectManageService {
    @Resource
    private SalesProjectManageMapper projectManageMapper;
    @Resource
    private SalesFileRelationMapper fileRelationMapper;
    @Resource
    private SalesChangeMapper changeMapper;
    @Resource
    private SalesFollowRecordMapper followRecordMapper;
    @Resource
    private SalesStageMapper stageMapper;
    @Resource
    private SalesAuditMapper auditMapper;
    @Resource
    private WorkFlowFeginService workFlowService;

    @Resource
    private FeginService feginService;
    @Resource
    private IDictionaryService dictionaryService;
    @Resource
    private IContractInfoService contractInfoService;
    @Resource
    private IPurchaseOrdeService purchaseOrdeService;
    @Resource
    private SalesOpportunityService salesOpportunityService;
    @Resource
    private PaymentPlanMapper paymentPlanMapper;
    @Resource
    private PaymentRecordsMapper paymentRecordsMapper;
    @Resource
    private ReceiptRecordsMapper receiptRecordsMapper;
    @Resource
    private PaymentRequestMapper paymentRequestMapper;
    @Resource
    private ProjectMemberService projectMemberService;

    @Resource
    private IPurchaseOrdeService PurchaseOrdeServiceImpl;

    @Resource
    private IApprovalService approvalService;
    @Resource
    private BrAndBmrMapper brAndBmrMapper;
    @Resource
    private BrAndBmrService brAndBmrService;
    @Resource
    private SalesProjectManageBackMapper projectManageBackMapper;
    @Resource
    private SalesProjectManageOneBackMapper projectManageOneBackMapper;
    @Resource
    private SalesAuditBackMapper auditBackMapper;
    @Resource
    private ReimburseService reimburseService;
    @Resource
    private SalesOpportunityMapper opportunityMapper;
    @Resource
    private ApprovalMapper approvalMapper;
    @Resource
    private SalesCostMigrateMapper costMigrateMapper;
    @Resource
    private PurchaseOrdeMapper purchaseOrdeMapper;
    @Resource
    private InternalPurchaseMapper internalPurchaseMapper;
    @Resource
    private RefundRecordsMapper refundRecordsMapper;
    @Resource
    private ProjectReturnedMoneyMapper returnedMoneyMapper;
    @Resource
    private TranspondEmailService transpondEmailService;

    @Resource
    private IInternalPurchaseService internalPurchaseService;

    @Value("${webSit.web}")
    private String webSitUrl;

    @Override
    public PageUtil<SalesProjectManageVO> queryProject(IPage<SalesProjectManageVO> page, SalesProjectManageVO projectManageVO, List<SysUserEntity> userList, String token) {
        if (projectManageVO.getOrderByProp() != null) {
            projectManageVO.setOrderByProp(StringUtils.camelToUnderline(projectManageVO.getOrderByProp()));
        }
        IPage<SalesProjectManageVO> iPage = projectManageMapper.queryProject(page, projectManageVO, userList);
        List<SalesProjectManageVO> list = iPage.getRecords();
        if (list != null && !list.isEmpty()) {
            List<SalesProjectManageVO> voList = projectManageMapper.queryProject(projectManageVO,userList);
            BigDecimal projectManageMoneyPage = new BigDecimal(0);
            BigDecimal projectManageMoneyTotal = new BigDecimal(0);
            BigDecimal projectExpectMoneyPage = new BigDecimal(0);
            BigDecimal projectExpectMoneyTotal = new BigDecimal(0);
            BigDecimal returnedMoneyPage = new BigDecimal(0);
            BigDecimal returnedMoneyTotal = new BigDecimal(0);
            BigDecimal invoicedMoneyPage = new BigDecimal(0);
            BigDecimal invoicedMoneyTotal = new BigDecimal(0);
            BigDecimal paymentedMoneyPage = new BigDecimal(0);
            BigDecimal paymentedMoneyTotal = new BigDecimal(0);

            BigDecimal purchaseMoneyPage = new BigDecimal(0);
            BigDecimal purchaseMoneyTotal = new BigDecimal(0);
            BigDecimal reimburseMoneyPage = new BigDecimal(0);
            BigDecimal reimburseMoneyTotal = new BigDecimal(0);
            BigDecimal projectMoneyPage = new BigDecimal(0);
            BigDecimal projectMoneyTotal = new BigDecimal(0);

            BigDecimal collectTicketedMoneyPage = new BigDecimal(0);
            BigDecimal collectTicketedMoneyTotal = new BigDecimal(0);
            for (SalesProjectManageVO item : list) {
                projectManageMoneyPage = projectManageMoneyPage.add(new BigDecimal(item.getProjectManageMoney().getValue()));
                projectExpectMoneyPage = projectExpectMoneyPage.add(new BigDecimal(item.getProjectExpectMoney()));
                returnedMoneyPage = returnedMoneyPage.add(new BigDecimal(item.getReturnedMoney()));
                purchaseMoneyPage = purchaseMoneyPage.add(new BigDecimal(item.getPurchaseMoney()));
                reimburseMoneyPage = reimburseMoneyPage.add(new BigDecimal(item.getReimburseMoney()));
                invoicedMoneyPage = invoicedMoneyPage.add(new BigDecimal(item.getInvoicedMoney()));
                paymentedMoneyPage = paymentedMoneyPage.add(new BigDecimal(item.getPaymentedMoney()));
                collectTicketedMoneyPage = collectTicketedMoneyPage.add(new BigDecimal(item.getCollectTicketedMoney()));
                projectMoneyPage = projectMoneyPage.add(new BigDecimal(item.getProjectMoney()));
            }
            for (SalesProjectManageVO item : voList) {
                projectManageMoneyTotal = projectManageMoneyTotal.add(new BigDecimal(item.getProjectManageMoney().getValue()));
                projectExpectMoneyTotal = projectExpectMoneyTotal.add(new BigDecimal(item.getProjectExpectMoney()));
                returnedMoneyTotal = returnedMoneyTotal.add(new BigDecimal(item.getReturnedMoney()));
                invoicedMoneyTotal = invoicedMoneyTotal.add(new BigDecimal(item.getInvoicedMoney()));
                paymentedMoneyTotal = paymentedMoneyTotal.add(new BigDecimal(item.getPaymentedMoney()));
                collectTicketedMoneyTotal = collectTicketedMoneyTotal.add(new BigDecimal(item.getCollectTicketedMoney()));
                purchaseMoneyTotal = purchaseMoneyTotal.add(new BigDecimal(item.getPurchaseMoney()));
                reimburseMoneyTotal = reimburseMoneyTotal.add(new BigDecimal(item.getReimburseMoney()));
                projectMoneyTotal = projectMoneyTotal.add(new BigDecimal(item.getProjectMoney()));
            }
            list.get(0).setProjectManageMoneyPage(String.valueOf(projectManageMoneyPage));
            list.get(0).setProjectManageMoneyTotal(String.valueOf(projectManageMoneyTotal));
            list.get(0).setProjectExpectMoneyPage(String.valueOf(projectExpectMoneyPage));
            list.get(0).setProjectExpectMoneyTotal(String.valueOf(projectExpectMoneyTotal));
            list.get(0).setReturnedMoneyPage(String.valueOf(returnedMoneyPage));
            list.get(0).setReturnedMoneyTotal(String.valueOf(returnedMoneyTotal));
            list.get(0).setInvoicedMoneyPage(String.valueOf(invoicedMoneyPage));
            list.get(0).setInvoicedMoneyTotal(String.valueOf(invoicedMoneyTotal));
            list.get(0).setPaymentedMoneyPage(String.valueOf(paymentedMoneyPage));
            list.get(0).setPaymentedMoneyTotal(String.valueOf(paymentedMoneyTotal));
            list.get(0).setCollectTicketedMoneyPage(String.valueOf(collectTicketedMoneyPage));
            list.get(0).setCollectTicketedMoneyTotal(String.valueOf(collectTicketedMoneyTotal));
            list.get(0).setPurchaseMoneyPage(String.valueOf(purchaseMoneyPage));
            list.get(0).setPurchaseMoneyTotal(String.valueOf(purchaseMoneyTotal));
            list.get(0).setReimburseMoneyPage(String.valueOf(reimburseMoneyPage));
            list.get(0).setReimburseMoneyTotal(String.valueOf(reimburseMoneyTotal));
            list.get(0).setProjectMoneyPage(String.valueOf(projectMoneyPage));
            list.get(0).setProjectMoneyTotal(String.valueOf(projectMoneyTotal));
            iPage.setRecords(list);
        }
        return new PageUtil<>(iPage);
    }
    @Override
    public PageUtil<SalesProjectManageVO> queryProjectAudit(IPage<SalesProjectManageVO> page, SalesProjectManageVO projectManageVO, List<SysUserEntity> userList, String token) {
        if (projectManageVO.getOrderByProp() != null) {
            projectManageVO.setOrderByProp(StringUtils.camelToUnderline(projectManageVO.getOrderByProp()));
        }
        IPage<SalesProjectManageVO> iPage = projectManageMapper.queryProjectAudit(page, projectManageVO);
        return new PageUtil<>(iPage);
    }
    @Override
    public List<SalesProjectManageVO> queryProject(SalesProjectManageVO projectManageVO, List<SysUserEntity> userList, String token) {
        if (projectManageVO.getOrderByProp() != null) {
            projectManageVO.setOrderByProp(StringUtils.camelToUnderline(projectManageVO.getOrderByProp()));
        }
        return projectManageMapper.queryProject(projectManageVO,userList);
    }
    @Override
    public SalesProjectManageVO queryProjectInfoByOppId(Integer oppId){
        return projectManageMapper.queryProjectInfoByOppId(oppId);
    }

    @Override
    public long queryTotal(SalesProjectManageVO projectManageVO, List<SysUserEntity> userList, String token) {
        return projectManageMapper.queryTotal(projectManageVO, userList);
    }

    @Override
    public SalesProjectManageVO queryProjectInfoById(Integer projectManageId,String token) {
        SalesProjectManageVO projectManageVO = projectManageMapper.selectByPrimaryKey(projectManageId);

        List<Integer> projectIdList = new ArrayList<>();
        projectIdList.add(projectManageId);
        FeeMainVO feeMainVO = new FeeMainVO();
        feeMainVO.setProjectIdList(projectIdList);
        BigDecimal sum = BigDecimal.ZERO;
        List<LinkedHashMap> resultList = (List<LinkedHashMap>) reimburseService.queryReimburseListByProjectIdListOrChanceIdList(feeMainVO,token).getResult();
        if (resultList != null && resultList.size() > 0){
            for (LinkedHashMap result : resultList) {
                if (Integer.parseInt(result.get("state").toString()) == 3){
                    // 从 LinkedHashMap 中提取属性
                    String reimburseMoney = result.get("reimburseMoney").toString();
                    String substring = reimburseMoney.substring("{value=".length(), reimburseMoney.length() - 1);
                    // 检查属性是否存在，以及类型是否匹配
                    if (substring != null) {
                        BigDecimal reimburseMoney1 = new BigDecimal(substring) ;
                        sum = sum.add(reimburseMoney1);
                    }
                }
            }
        }
        if (sum.compareTo(BigDecimal.ZERO) > 0){
            projectManageVO.setReimburseMoney(String.valueOf(sum));
        }else{
            projectManageVO.setReimburseMoney("0.00");
        }
        List<SalesFileRelationVO> fileRelationVOS = fileRelationMapper.queryFileInfoList(projectManageId, Constants.PROJECT_MODEL_ID);
        if (!fileRelationVOS.isEmpty()) {
            projectManageVO.setSalesFileRelationVO(fileRelationVOS);
        }
        projectManageVO.setSenderList(transpondEmailService.queryTranspondByApprovalId(projectManageVO.getApprovalIdOne()));
        return projectManageVO;
    }

    public ActivitiVO toWorkFlow(SysUserEntity user, String token) {
        ActivitiVO activitiVO = new ActivitiVO();
        activitiVO.setAuthorization(user.getAccount());
        activitiVO.setProcessName("项目信息审批流程");
        activitiVO.setProcessCode("project_approval");
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("leader",user.getAccount());
        activitiVO.setCustomParams(paramMap);
        ActivitiVO workFlowResult = workFlowService.startProcessByDesignCodeVersionBatchCustomParams(activitiVO).getResult();
        return workFlowResult;
    }
    //创项成功同时迁移机会点的费用信息，免审
    public int migrateCost(SalesProjectManageVO projectManageVO, String token) {
        //报销迁移
        FeeMainVO vo = new FeeMainVO();
        vo.setChanceId(projectManageVO.getProjectOpportunityId());
        vo.setProjectId(projectManageVO.getProjectManageId());
        reimburseService.updateProjectIdByChanceId(vo,token);
        SalesAuditVO auditVO = new SalesAuditVO();
        auditVO.setSalesRelationId(projectManageVO.getProjectOpportunityId());
        auditVO.setAuditClass(Constants.COST_MODEL_ID);
        auditVO.setSalesMigrateId(projectManageVO.getProjectManageId());
        ApprovalVO approval = approvalService.initApprovalAndLog(0, Constants.COSTMIGRATE_TASK_TYPE,
                "费用迁移审批流程", "",-1,"免审");
        auditVO.setBusinessId(approval.getApprovalId());
        approvalService.insertApprovalLog(auditVO.getBusinessId(),"通过", "系统判定跳过",auditVO.getProcessComments());
        approvalService.approved(null,auditVO.getBusinessId());
        //费用迁移成功，更改费用记录信息
        SalesCostMigrateVO costMigrateVO = new SalesCostMigrateVO();
        costMigrateVO.setOpportunityId(auditVO.getSalesRelationId());
        costMigrateVO.setProjectManageId(auditVO.getSalesMigrateId());
        costMigrateVO.setMigrateState(1);
        costMigrateMapper.updateCostOfProject(costMigrateVO);
        return auditMapper.insert(auditVO);
    }

    //创项成功的同时更改机会点审核状态，免审
    public int opportunityAudit(SalesProjectManageVO projectManageVO, String token) {
        SalesOpportunityVO opportunityVO = opportunityMapper.selectByPrimaryKey(projectManageVO.getProjectOpportunityId());
        // // 获取模块管理员第一人作为待办审批人
//        List<SysUserEntity> users = dictionaryService.queryMenuUserIdsByCode("opportunityManager");
//        SysUserEntity todoUser = feginService.searchUserInfoByIds(users.get(0).getUserId(), token).getResult();
        ApprovalVO approval = approvalService.initApprovalAndLog(0, Constants.OPPORTUNITY_AUDIT_TASK_TYPE,
                "机会状态变更审批", "",-1,"免审");
        opportunityVO.setBusinessId(approval.getApprovalId());
        approvalService.insertApprovalLog(opportunityVO.getBusinessId(),"通过", "系统判定跳过",opportunityVO.getProcessComments());
        approvalService.approved(null,opportunityVO.getBusinessId());
//        SalesStageVO stageVO = stageMapper.queryStageInfo(opportunityVO.getOpportunityId(), Constants.OPPORTUNITY_MODEL_ID).get(0);
//        stageMapper.updateByPrimaryKeySelective(stageVO);
        //费用迁移，更改机会点迁移状态 已迁移
        opportunityVO.setMigrateState(1);
        return opportunityMapper.updateByPrimaryKeySelective(opportunityVO);
    }

    @Override
    public int addProject(SalesProjectManageVO projectManageVO, String token) {
        projectManageMapper.insert(projectManageVO);
        Integer projectManageId = projectManageVO.getProjectManageId();
        SalesProjectManageVO manageVO = projectManageMapper.selectByPrimaryKey(projectManageId);
        manageVO.setReasonApplicationOne(projectManageVO.getReasonApplicationOne());
        manageVO.setSenderList(projectManageVO.getSenderList());
        SalesStageVO stageVO = new SalesStageVO();
        stageVO.setSalesRelationId(projectManageId);
        stageVO.setStageClass(Constants.PROJECT_MODEL_ID);
        stageVO.setStageStateId(manageVO.getStageStateId() == null ? 1 : manageVO.getStageStateId());
        stageMapper.insert(stageVO);
        firstReview(manageVO, token);
        //机会采购绑定项目ID
        purchaseOrdeMapper.updatePurchaseProjectIdByOpId(projectManageId,projectManageVO.getProjectOpportunityId());
        //机会内部采购绑定项目ID
        internalPurchaseMapper.updatePurchaseProjectIdByOpId(projectManageId,projectManageVO.getProjectOpportunityId());
        //机会收票绑定项目ID
        receiptRecordsMapper.updateReceiptRecordsProjectIdByOpId(projectManageId,projectManageVO.getProjectOpportunityId());
        //机会付款申请绑定项目ID
        paymentRequestMapper.updatePayRequestsProjectIdByOpId(projectManageId,projectManageVO.getProjectOpportunityId());
        //机会付款记录绑定项目ID
        paymentRecordsMapper.updatePayRecordRecordsProjectIdByOpId(projectManageId,projectManageVO.getProjectOpportunityId());
        //机会退款记录绑定项目ID
        refundRecordsMapper.updateRefundRecordsProjectIdByOpId(projectManageId,projectManageVO.getProjectOpportunityId());
        return projectManageId;
    }

    //获取抄送邮箱
    private String getCopyForUserEmails(List<SysUserEntity> userList) {
        StringBuilder copyForUserEmails = new StringBuilder();           // 抄送人邮箱
        if (!userList.isEmpty()) {      // 根据抄送用户对象拼接抄送人邮箱
            for (SysUserEntity copyForUser : userList) {
                copyForUserEmails.append(copyForUser.getEmail()).append(",");
            }
            // 移除最后一个逗号
            copyForUserEmails.replace(copyForUserEmails.lastIndexOf(","), copyForUserEmails.length(), "");
        }
        return copyForUserEmails.toString();
    }

    public String getMessageInfo(SalesProjectManageVO projectManageVO,String record,Integer todoUserId,Integer workState,Boolean flag,String token) {
        //获取人员信息
        ResponseAPI<SysUserEntity> res = feginService.searchUserInfoByIds(todoUserId, token);
        SysUserEntity user = res.getResult();
        JSONObject userObject = feginService.getUserInfo(token);
        List<String> classfiedCode = new ArrayList<>();
        classfiedCode.add("projectType");
        classfiedCode.add("projectClasses");
        classfiedCode.add("projectDifferentId");
        Map<String, List<DictionaryLookupItemVO>> listMap = dictionaryService.queryDictionaryLookupInfo(1, classfiedCode);
        String msg;
        if (workState == 0) {
            msg = "<div><p>" + "尊敬的" + user.getLoginName() + "：</p></div>" +
                    "<div><p style='text-indent: 2em'>" + record + "</p></div>" +
                    "<div><p style='text-indent: 2em'>项目编号：" + projectManageVO.getProjectNumber() + "</p></div>" +
                    "<div><p style='text-indent: 2em'>项目名称：" + projectManageVO.getProjectTheme() + "</p></div>" +
                    "<div><p style='text-indent: 2em'>机会名称：" + getOpportunityTheme(projectManageVO.getProjectOpportunityId()) + "</p></div>" +
                    "<div><p style='text-indent: 2em'>客户名称：" + projectManageVO.getCustomerName() + "</p></div>" +
                    "<div><p style='text-indent: 2em'>项目类别：" + getCRMDictionaryNameByCode("projectClasses", listMap).get(projectManageVO.getProjectClasses().toString()) + "</p></div>" +
                    "<div><p style='text-indent: 2em'>项目类型：" + getCRMDictionaryNameByCode("projectDifferentId", listMap).get(projectManageVO.getProjectDifferentId().toString()) + "</p></div>" +
                    "<div><p style='text-indent: 2em'>立项时间：" + new SimpleDateFormat("yyyy-MM-dd").format(projectManageVO.getProjectCreatetime()) + "</p></div>" +
                    "<div><p style='text-indent: 2em'>项目总额：" + projectManageVO.getProjectExpectMoney() + "元</p></div>" +
                    "<div><p style='text-indent: 2em'>申请人：" + getUserNameById(userObject).get(projectManageVO.getLastUpdateBy()) + " / " + getUserAccountById(userObject).get(projectManageVO.getLastUpdateBy()) + "</p></div>" +
                    "<div><p style='text-indent: 2em'>申请时间：" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(projectManageVO.getLastUpdateTime()) + "</p></div>" +
                    "<div><p style='text-indent: 2em'>申请原因：" + (projectManageVO.getReasonApplication() == null ? "无" : projectManageVO.getReasonApplication()) + "</p></div>" +
                    "<div><p style='text-indent: 2em'>系统审批路径：客户关系管理系统 - 待办事项 - 待办审批 "+
                    "<a href='"+webSitUrl+"/?m=crm&p=crmtodoItems&me=todoApprovalPath'>进入</a></p></div>"+
                    "<div><p style='text-indent: 2em'>谢谢！</p></div>"+
                    "<div><p style='text-indent: 2em'>说明：该邮件为系统自动发送，请勿回复。</p></div>";
        } else {
            msg = "<div><p>" + "尊敬的" + user.getLoginName() + "：</p></div>" +
                    "<div><p style='text-indent: 2em'>" + record + "</p></div>" +
                    "<div><p style='text-indent: 2em'>项目编号：" + projectManageVO.getProjectNumber() + "</p></div>" +
                    "<div><p style='text-indent: 2em'>项目名称：" + projectManageVO.getProjectTheme() + "</p></div>" +
                    "<div><p style='text-indent: 2em'>机会名称：" + projectManageVO.getOpportunityTheme() + "</p></div>" +
                    "<div><p style='text-indent: 2em'>客户名称：" + projectManageVO.getCustomerName() + "</p></div>" +
                    "<div><p style='text-indent: 2em'>项目类别：" + getCRMDictionaryNameByCode("projectClasses", listMap).get(projectManageVO.getProjectClasses().toString()) + "</p></div>" +
                    "<div><p style='text-indent: 2em'>项目类型：" + getCRMDictionaryNameByCode("projectDifferentId", listMap).get(projectManageVO.getProjectDifferentId().toString()) + "</p></div>" +
                    "<div><p style='text-indent: 2em'>立项时间：" + new SimpleDateFormat("yyyy-MM-dd").format(projectManageVO.getProjectCreatetime()) + "</p></div>" +
                    "<div><p style='text-indent: 2em'>项目总额：" + projectManageVO.getProjectExpectMoney() + "元</p></div>" +
                    (flag ? "" : "<div><p style='text-indent: 2em'>审批意见：" + (projectManageVO.getProcessComments() == null ? "无" : projectManageVO.getProcessComments()) + "</p></div>") +
                    "<div><p style='text-indent: 2em'>审批时间：" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Timestamp(System.currentTimeMillis())) + "</p></div>" +
                    "<div><p style='text-indent: 2em'>系统查看路径：客户关系管理系统 - 项目信息管理 - 项目信息 "+
                    "<a href='"+webSitUrl+"/?m=crm&p=projectmanage&me=projectmanageInfo'>进入</a></p></div>"+
                    "<div><p style='text-indent: 2em'>谢谢！</p></div>"+
                    "<div><p style='text-indent: 2em'>说明：该邮件为系统自动发送，请勿回复。</p></div>";
        }
        return msg;
    }

    // 给负责人发送邮件通知
    public void sendEmail(SalesProjectManageVO record, String token,String state) {
        SalesProjectManageVO projectManageVO = projectManageMapper.selectByPrimaryKey(record.getProjectManageId());
//        List<SysUserEntity> copyUserIList = dictionaryService.queryCcUserIdsByCode("projectManage");
//        String copyForUserEmails = getCopyForUserEmails(copyUserIList);       // 抄送人邮箱
        ResponseAPI<SysUserEntity> res = feginService.searchUserInfoByIds(projectManageVO.getProjectPrincipal(), token);
        SysUserEntity user = res.getResult();
        // 获取所有用户信息
        List<SysUserEntity> allUser = feginService.getUserIgnoreFlag(token).getResult();
        String title = "【系统通知】项目信息" + state + " - 流程单提醒通知";
        String msg = "<div><p>" + "尊敬的" + user.getLoginName() + "：</p></div>" +
                "<div><p style='text-indent: 2em'>您好，您有一个新的项目信息" + state + "审批已经发起：</p></div>" +
                "<div><p style='text-indent: 2em'>项目编号：" + projectManageVO.getProjectNumber() + "</p></div>" +
                "<div><p style='text-indent: 2em'>项目名称：" + projectManageVO.getProjectTheme() + "</p></div>" +
                "<div><p style='text-indent: 2em'>机会名称：" + projectManageVO.getOpportunityTheme() + "</p></div>" +
                "<div><p style='text-indent: 2em'>客户名称：" + projectManageVO.getCustomerName() + "</p></div>" +
                "<div><p style='text-indent: 2em'>系统查看路径：客户关系管理系统 - 项目信息管理 - 项目信息 "+
                "<a href='"+webSitUrl+"/?m=crm&p=projectmanage&me=projectmanageInfo'>进入</a></p></div>"+
                "<div><p style='text-indent: 2em'>谢谢！</p></div>"+
                "<div><p style='text-indent: 2em'>说明：该邮件为系统自动发送，请勿回复。</p></div>";
        String principalEmail = allUser.stream().filter(p -> Objects.equals(p.getUserId(), projectManageVO.getProjectPrincipal())).toList().get(0).getEmail();
        CompletableFuture.runAsync(() -> EmailUtils.sentMailByAddressee(principalEmail, null, title, msg, token));
    }

    @Override
    public int updateProject(SalesProjectManageVO projectManageVO, String token) {
        SalesProjectManageVO oldPm = projectManageMapper.selectByPrimaryKey(projectManageVO.getProjectManageId());
        if (projectManageVO.getApproveState() != 1){
            firstReview(projectManageVO, token);
        }
        if (projectManageVO.getApproveState() == 1 && projectManageVO.getProjectState() == 2) {
            boolean review = projectMemberService.testFinalReview(projectManageVO, token);
            if (!review) {
                return -1;
            }
            List<ProjectUpdateInfoVO> voList = projectManageMapper.queryUpdateInfoOnLineById(projectManageVO.getProjectManageId());
            if (!voList.isEmpty()) {
                return -1;
            }
            projectManageVO = finalReview(projectManageVO, token);
        }
        //创建变更记录
        createRecord(oldPm,projectManageVO,token);
        //负责人变更时
        if (!oldPm.getProjectPrincipal().equals(projectManageVO.getProjectPrincipal())) {
            ProjectReturnedMoneyVO returnedMoneyVO = new ProjectReturnedMoneyVO();
            returnedMoneyVO.setProjectManageId(projectManageVO.getProjectManageId());
            List<ProjectReturnedMoneyVO> voList = returnedMoneyMapper.queryReturnedMoneyList(returnedMoneyVO);
            for (ProjectReturnedMoneyVO recordVO:voList) {
                if (recordVO.getFlag() == 1) {//已发过消息的关闭消息
                    CompletableFuture.runAsync(() -> NoticUtils.pushNotics(recordVO.getBmpId(), new Timestamp(System.currentTimeMillis()), recordVO.getReturnedPrincipal(), 1, 36, recordVO.getReturnedPrincipal(), null));
                }
                if (recordVO.getProjectState() == 2) {//逾期的发送提醒
                    SalesProjectManageVO finalProjectManageVO = projectManageVO;
                    CompletableFuture.runAsync(() -> NoticUtils.pushNotics(recordVO.getBmpId(), new Timestamp(System.currentTimeMillis()), recordVO.getReturnedPrincipal(), 0, 36, recordVO.getReturnedPrincipal(), null));
                }
            }
        }
        return projectManageMapper.updateByPrimaryKeySelective(projectManageVO);
    }

    /**
     * 初验
     * @param projectManageVO
     * @param token
     */
    public void firstReview(SalesProjectManageVO projectManageVO, String token) {
        //获取审批人
        SysUserEntity commercialSpecial = dictionaryService.queryMenuUserIdsByCode("commercialSpecialist").get(0);
//        SysUserEntity finance = dictionaryService.queryMenuUserIdsByCode("finance").get(0);
//        SysUserEntity president = dictionaryService.queryMenuUserIdsByCode("president").get(0);
        //启动工作流
        ActivitiVO activitiVO = new ActivitiVO();
        activitiVO.setAuthorization(AuthUtils.getUserAccount());
        activitiVO.setProcessName("项目信息初验流程");
        activitiVO.setProcessCode("project_approval_one");
        activitiVO.setNextNodeParams("commercialSpecialist");
        activitiVO.setNextNodeAssignee(commercialSpecial.getAccount());
//        Map<String, Object> paramMap = new HashMap<>();
//        paramMap.put("commercialSpecialist", commercialSpecial.getAccount());
//        paramMap.put("finance",finance.getAccount());
//        paramMap.put("president", president.getAccount());
//        activitiVO.setCustomParams(paramMap);
//        ActivitiVO workFlowResult = workFlowService.startProcessByDesignCodeVersionBatchCustomParams(activitiVO).getResult();
        ActivitiVO workFlowResult = workFlowService.startMaxVersionProcessByDesignCodeCustomParams(activitiVO).getResult();
        ApprovalVO approval = approvalService.initApprovalAndLog(workFlowResult.getBusinessId(), Constants.PROJECT_TASK_TYPE_ONE,
                projectManageVO.getReasonApplicationOne(), "",-1,"");
        List<SalesAuditVO> auditVOS = auditMapper.queryAuditInfo(projectManageVO.getProjectManageId(), Constants.PROJECT_MODEL_ID);
        SalesAuditVO auditVO = new SalesAuditVO();
        if (auditVOS == null || auditVOS.isEmpty()) {
            auditVO.setReasonApplication(projectManageVO.getReasonApplicationOne());
            auditVO.setSalesRelationId(projectManageVO.getProjectManageId());
            auditVO.setAuditClass(Constants.PROJECT_MODEL_ID);
            auditVO.setBusinessId(approval.getApprovalId());
            auditVO.setLastUpdateBy(AuthUtils.getUserId());
            auditVO.setLastUpdateTime(new Timestamp(System.currentTimeMillis()));
            auditMapper.insert(auditVO);
        } else {
            auditVO = auditVOS.get(0);
            auditVO.setReasonApplication(projectManageVO.getReasonApplicationOne());
            auditVO.setSalesRelationId(projectManageVO.getProjectManageId());
            auditVO.setAuditClass(Constants.PROJECT_MODEL_ID);
            auditVO.setBusinessId(approval.getApprovalId());
            auditVO.setLastUpdateBy(AuthUtils.getUserId());
            auditVO.setLastUpdateTime(new Timestamp(System.currentTimeMillis()));
            auditBackMapper.insertBackInfo(auditVO.getSalesRelationId(), Constants.PROJECT_MODEL_ID);
            projectManageOneBackMapper.insertBackInfo(auditVO.getSalesRelationId(), Constants.PROJECT_MODEL_ID);
            auditMapper.updateByPrimaryKeySelective(auditVO);
        }
        Integer approveState = projectManageMapper.selectByPrimaryKey(projectManageVO.getProjectManageId()).getApproveState();
        // 转发人记录
        if (projectManageVO.getSenderList() != null && !projectManageVO.getSenderList().isEmpty()){
            transpondEmailService.insertTranspondEmailInfoByUser(approval.getApprovalId(),projectManageVO.getSenderList());
        }
        if (approveState != 1) {
            if (commercialSpecial.getUserId().equals(AuthUtils.getUserId())){
                //跳过第一步审批
                this.approveProjectInfoOne(projectManageVO,token,true);
            }else{
               // sendEmail(projectManageVO, token,"初验");
                approvalService.updateNextApproverByApprovalId(commercialSpecial.getUserId(),approval.getApprovalId());
//                List<SysUserEntity> copyUserIList = dictionaryService.queryCcUserIdsByCode("projectManage");
//            String copyForUserEmails = getCopyForUserEmails(copyUserIList);       // 抄送人邮箱
                //发送邮件
//                String titel = "【系统通知】项目信息初验 - 流程单审批通知";
//                String record = "您好，您有一个新的项目信息初验审批需要处理：";
//                projectManageVO.setReasonApplication(projectManageVO.getReasonApplicationOne());
//                String msg = getMessageInfo(projectManageVO,record,commercialSpecial.getUserId(),0,true,token);
//                CompletableFuture.runAsync(() -> EmailUtils.sentMailByAddressee(commercialSpecial.getEmail(), null, titel, msg, token));
                //调用通知接口
                SalesAuditVO finalAuditVO = auditVO;
                CompletableFuture.runAsync(() -> NoticUtils.pushNotic(finalAuditVO.getBusinessId(), finalAuditVO.getLastUpdateTime(), finalAuditVO.getLastUpdateBy(), 0, Constants.PROJECT_TASK_TYPE_ONE, commercialSpecial.getUserId(), token));
            }
        }
    }

    /**
     * 终验
     * @param projectManageVO
     * @param token
     */
    public SalesProjectManageVO finalReview(SalesProjectManageVO projectManageVO, String token) {
        //获取审批人
        SysUserEntity commercialSpecial = dictionaryService.queryMenuUserIdsByCode("commercialSpecialist").get(0);
//        SysUserEntity finance = dictionaryService.queryMenuUserIdsByCode("finance").get(0);
//        SysUserEntity president = dictionaryService.queryMenuUserIdsByCode("president").get(0);
        //启动工作流
        ActivitiVO activitiVO = new ActivitiVO();
        activitiVO.setAuthorization(AuthUtils.getUserAccount());
        activitiVO.setProcessName("项目信息终验流程");
        activitiVO.setProcessCode("project_approval");
        activitiVO.setNextNodeParams("commercialSpecialist");
        activitiVO.setNextNodeAssignee(commercialSpecial.getAccount());
//        Map<String, Object> paramMap = new HashMap<>();
//        paramMap.put("commercialSpecialist", commercialSpecial.getAccount());
//        paramMap.put("finance",finance.getAccount());
//        paramMap.put("president", president.getAccount());
//        activitiVO.setCustomParams(paramMap);
//        ActivitiVO workFlowResult = workFlowService.startProcessByDesignCodeVersionBatchCustomParams(activitiVO).getResult();
        ActivitiVO workFlowResult = workFlowService.startMaxVersionProcessByDesignCodeCustomParams(activitiVO).getResult();
        ApprovalVO approval = approvalService.initApprovalAndLog(workFlowResult.getBusinessId(), Constants.PROJECT_TASK_TYPE,
                projectManageVO.getReasonApplication(), "",-1,"");
        projectManageVO.setBusinessId(approval.getApprovalId());
        projectManageVO.setLastUpdateBy(AuthUtils.getUserId());
        projectManageVO.setLastUpdateTime(new Timestamp(System.currentTimeMillis()));
        projectManageBackMapper.insertBackInfo(projectManageVO.getProjectManageId());
        SalesProjectManageVO vo = projectManageMapper.selectByPrimaryKey(projectManageVO.getProjectManageId());
        Integer approveState = vo.getApproveState();
        Integer auditState = vo.getAuditState();
        if (approveState == 1 && auditState != 1) {
            if (commercialSpecial.getUserId().equals(AuthUtils.getUserId())){
                //跳过第一步审批
                this.approveProjectInfo(projectManageVO,token,true);
            }else{
               // sendEmail(projectManageVO, token,"终验");
                approvalService.updateNextApproverByApprovalId(commercialSpecial.getUserId(),approval.getApprovalId());
//                List<SysUserEntity> copyUserIList = dictionaryService.queryCcUserIdsByCode("projectManage");
    //            String copyForUserEmails = getCopyForUserEmails(copyUserIList);       // 抄送人邮箱
                //发送邮件
//                String titel = "【系统通知】项目信息终验 - 流程单审批通知";
//                String record = "您好，您有一个新的项目信息终验审批需要处理：";
//                String msg = getMessageInfo(projectManageVO,record,commercialSpecial.getUserId(),0,true,token);
//                CompletableFuture.runAsync(() -> EmailUtils.sentMailByAddressee(commercialSpecial.getEmail(), null, titel, msg, token));
                //调用通知接口
                CompletableFuture.runAsync(() -> NoticUtils.pushNotic(projectManageVO.getBusinessId(), projectManageVO.getLastUpdateTime(),projectManageVO.getLastUpdateBy(),  0, Constants.PROJECT_TASK_TYPE, commercialSpecial.getUserId(), token));
            }
        }
        // 转发人记录
        if (projectManageVO.getSenderList() != null && !projectManageVO.getSenderList().isEmpty()){
            transpondEmailService.insertTranspondEmailInfoByUser(approval.getApprovalId(),projectManageVO.getSenderList());
        }
        return projectManageVO;
    }

    public void createRecord(SalesProjectManageVO oldPm,SalesProjectManageVO newPm, String token) {
        Integer userId = AuthUtils.getUserId();
        StringBuffer sb = new StringBuffer();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        List<String> statesList = new ArrayList<>();
        statesList.add("projectState");
//            statesList.add("projectApprovalState");
        JSONObject userObject = feginService.getUserInfo(token);
        JSONObject jsonObject = feginService.queryDictionaryLookupInfo("crm", statesList);
        List<String> classfiedCode = new ArrayList<>();
        classfiedCode.add("projectType");
        classfiedCode.add("projectClasses");
        classfiedCode.add("projectDifferentId");
        Map<String, List<DictionaryLookupItemVO>> listMap = dictionaryService.queryDictionaryLookupInfo(1, classfiedCode);
//        String userInfo = getUserNameById(userObject).get(userId) + " / " + getUserAccountById(userObject).get(userId);
        DecimalFormat formatter = new DecimalFormat("#,##0.00");
        sb.append(compare("项目归属", (String) getCRMDictionaryNameByCode("projectType", listMap).get(oldPm.getProjectType().toString()), (String) getCRMDictionaryNameByCode("projectType", listMap).get(newPm.getProjectType().toString())))
            .append(compare("项目类别", (String) getCRMDictionaryNameByCode("projectClasses", listMap).get(oldPm.getProjectClasses().toString()), (String) getCRMDictionaryNameByCode("projectClasses", listMap).get(newPm.getProjectClasses().toString())))
            .append(compare("项目状态", (String) getDictionaryNameByCode("projectState", jsonObject).get(oldPm.getProjectState().toString()), (String) getDictionaryNameByCode("projectState", jsonObject).get(newPm.getProjectState().toString())))
            .append(compare("立项时间", dateFormat.format(oldPm.getProjectCreatetime()), dateFormat.format(newPm.getProjectCreatetime())))
            .append(compare("项目类型", (String) getCRMDictionaryNameByCode("projectDifferentId", listMap).get(oldPm.getProjectDifferentId().toString()), (String) getCRMDictionaryNameByCode("projectDifferentId", listMap).get(newPm.getProjectDifferentId().toString())))
            .append(compare("考核利润", formatter.format(Double.valueOf(oldPm.getProjectManageMoney().getValue())), formatter.format(Double.valueOf(newPm.getProjectManageMoney().getValue()))))
            .append(compare("项目金额",oldPm.getProjectMoney(),newPm.getProjectMoney()));
        SalesChangeVO salesChangeVO = new SalesChangeVO();
        salesChangeVO.setSalesRelationId(newPm.getProjectManageId());
        salesChangeVO.setChangeClass(Constants.PROJECT_MODEL_ID);
        if (sb.length() > 0) {
            sb.replace(sb.length() - 1,sb.length(), "");
            salesChangeVO.setChangeInfo(sb.toString());
            changeMapper.insert(salesChangeVO);
        }
    }

    public String compare(String pre, String oldValue, String newValue) {
        if (!Objects.equals(oldValue, newValue)) {
            return pre + "从【" + oldValue + "】变更为【" + newValue + "】，";
        }
        return "";
    }

    private Map getUserNameById(JSONObject jsonObject) {
        List<Map> dataDictionaryArray = (List) jsonObject.get("result");
        Map<Integer, String> map = new HashMap<>();
        if (!CollectionUtils.isEmpty(dataDictionaryArray)) {
            for (Map item : dataDictionaryArray) {
                map.put((Integer) item.get("userId"), (String) item.get("loginName"));
            }
            return map;
        }
        return null;
    }

    private Map getUserAccountById(JSONObject jsonObject) {
        List<Map> dataDictionaryArray = (List) jsonObject.get("result");
        Map<Integer, String> map = new HashMap<>();
        if (!CollectionUtils.isEmpty(dataDictionaryArray)) {
            for (Map item : dataDictionaryArray) {
                map.put((Integer) item.get("userId"), (String) item.get("account"));
            }
            return map;
        }
        return null;
    }

    private Map getDictionaryNameByCode(String itemCode, JSONObject jsonObject) {
        LinkedHashMap linkedHashMap = (LinkedHashMap) jsonObject.get("result");
        List<Map> dataDictionaryArray = (List) linkedHashMap.get(itemCode);
        Map<String, String> map = new HashMap<>();
        if (!CollectionUtils.isEmpty(dataDictionaryArray)) {
            for (Map item : dataDictionaryArray) {
                map.put(item.get("itemCode").toString(), item.get("itemName").toString());
            }
            return map;
        }
        return null;
    }

    private Map getCRMDictionaryNameByCode(String itemCode, Map listMap) {
//        LinkedHashMap linkedHashMap = (LinkedHashMap) listMap.get("result");
        List<DictionaryLookupItemVO> dataDictionaryArray = (List) listMap.get(itemCode);
        Map<String, String> map = new HashMap<>();
        if (!CollectionUtils.isEmpty(dataDictionaryArray)) {
            for (DictionaryLookupItemVO item : dataDictionaryArray) {
                map.put(item.getItemCode(), item.getItemName());
            }
            return map;
        }
        return null;
    }

    private String getOpportunityTheme(Integer opId) {
        SalesOpportunityVO record = new SalesOpportunityVO();
        record.setOpportunityState(2);
//        QueryWrapper<SalesOpportunityVO> queryWrapper = QueryWrapperGenerator.opStateQueryWrapper(record);
        List<SalesOpportunityVO> list = salesOpportunityService.selectAllOpInfo(record);
        if (!CollectionUtils.isEmpty(list)) {
            for (SalesOpportunityVO item : list) {
                if (item.getOpportunityId().equals(opId)) {
                    return item.getOpportunityTheme();
                }
            }
            return null;
        }
        return null;
    }
    private String getOpportunityCustomer(Integer opId) {
        SalesOpportunityVO record = new SalesOpportunityVO();
        record.setOpportunityState(2);
//        QueryWrapper<SalesOpportunityVO> queryWrapper = QueryWrapperGenerator.opStateQueryWrapper(record);
        List<SalesOpportunityVO> list = salesOpportunityService.selectAllOpInfo(record);
        if (!CollectionUtils.isEmpty(list)) {
            for (SalesOpportunityVO item : list) {
                if (item.getOpportunityId().equals(opId)) {
                    return item.getCustomerName();
                }
            }
            return null;
        }
        return null;
    }

    @Override
    public List<String> queryFileInfoList(Integer projectManageId) {
        List<SalesFileRelationVO> salesFileRelationVOS = fileRelationMapper.queryFileInfoList(projectManageId, Constants.PROJECT_MODEL_ID);
        return salesFileRelationVOS.stream().map(SalesFileRelationVO::getFileId).collect(Collectors.toList());
    }

    @Override
    public void addProjectFileRelation(Integer projectManageId, List<FileUploadRecordVO> fileIds) {
        fileRelationMapper.addFileRelation(projectManageId, fileIds, Constants.PROJECT_MODEL_ID);
    }

    @Override
    public List<SalesChangeVO> queryChangeInfo(Integer projectManageId) {
        return changeMapper.queryChangeInfo(projectManageId, Constants.PROJECT_MODEL_ID);
    }

    @Override
    public List<SalesFollowRecordVO> queryFollowRecord(Integer projectManageId) {
        return followRecordMapper.queryFollowRecord(projectManageId, Constants.PROJECT_MODEL_ID);
    }

    @Override
    public int addFollowRecord(SalesFollowRecordVO salesFollowRecordVO) {
        salesFollowRecordVO.setFollowClass(Constants.PROJECT_MODEL_ID);
        return followRecordMapper.insert(salesFollowRecordVO);
    }

    @Override
    public int updateFollowRecord(SalesFollowRecordVO salesFollowRecordVO) {
        return followRecordMapper.updateByPrimaryKeySelective(salesFollowRecordVO);
    }

    @Override
    public boolean deleteFollowRecords(Integer recordId) {
        int i = followRecordMapper.deleteByPrimaryKey(Long.valueOf(recordId));
        if (i > 0) { return true;}
        return false;
    }

    @Override
    public List<SalesStageVO> queryStageInfo(Integer projectManageId) {
        return stageMapper.queryStageInfo(projectManageId, 2);
    }

    @Override
    public int addStageInfo(SalesStageVO salesStageVO) {
        int i = stageMapper.insert(salesStageVO);
        SalesProjectManageVO projectManageVO = new SalesProjectManageVO();
        projectManageVO.setStageStateId(salesStageVO.getStageStateId());
        projectManageVO.setProjectManageId(salesStageVO.getSalesRelationId());
        Timestamp now = new Timestamp(System.currentTimeMillis());
        projectManageVO.setStageUpdateTime(now);
        projectManageMapper.updateByPrimaryKeySelective(projectManageVO);
        return i;
    }

    @Override
    public int updateStageInfo(SalesStageVO salesStageVO) {
        return stageMapper.updateByPrimaryKeySelective(salesStageVO);
    }

    @Override
    public List<SalesAuditVO> queryAuditInfo(Integer projectManageId) {
        return auditMapper.queryAuditInfo(projectManageId, Constants.PROJECT_MODEL_ID);
    }

    @Override
    public int addAuditInfo(SalesAuditVO salesAuditVO) {
        return auditMapper.insert(salesAuditVO);
    }

    @Override
    public int updateAuditInfo(SalesAuditVO salesAuditVO) {
        return auditMapper.updateByPrimaryKeySelective(salesAuditVO);
    }

    @Override
    public List<Integer> queryProjectOfOpportunity() {
        List<SalesProjectManageVO> projectManageVOS = projectManageMapper.queryProjectOfOpportunity();
        return projectManageVOS.stream().filter(item ->  !Objects.isNull(item) && !Objects.isNull(item.getProjectManageId())).map(SalesProjectManageVO::getProjectOpportunityId).collect(Collectors.toList());
    }

    /**
     * 初验通过
     *
     * @param projectManageVO
     * @return
     */
    public Boolean approveProjectInfoOne(SalesProjectManageVO projectManageVO, String token,Boolean auto) {
        List<SalesAuditVO> auditVOS = auditMapper.queryAuditInfo(projectManageVO.getProjectManageId(), Constants.PROJECT_MODEL_ID);
        SalesAuditVO auditVO = auditVOS.get(0);
        ActivitiVO activitiVO = new ActivitiVO();
        activitiVO.setAuthorization(AuthUtils.getUserAccount());
        ApprovalVO approvalVO = approvalService.queryApprovalByAppID(auditVO.getBusinessId());
        activitiVO.setBusinessId(approvalVO.getBusinessId());
        //获取当前所处节点
        ActivitiVO workFlowResult = workFlowService.getProcessNodeNameAndCode(activitiVO).getResult();
        SysUserEntity user = null;//邮件(下一处理人)
        Integer workState;
        String titel;
        String msg;
        Integer todoUser;//消息
        String copyForUserEmails = null;
        SysUserEntity askUser = feginService.searchUserInfoById(approvalVO.getCreator(), token).getResult();
        //记录审批日志
        if(auto){
            approvalService.insertApprovalLog(auditVO.getBusinessId(),"通过", "系统判定跳过",projectManageVO.getProcessComments());
        }else {
            approvalService.insertApprovalLog(auditVO.getBusinessId(),"通过", "项目信息审批",projectManageVO.getProcessComments());
        }
        if ("售后".equals(workFlowResult.getName())){
            // 审批通过
            workFlowService.approvalProcessByBusinessId(activitiVO);
            user = askUser;
            titel = "【系统通知】项目信息初验 - 流程单审批通过通知";
            workState = 1;
            String record = "您好，您申请的项目信息审批已经通过：";
            todoUser = 0;
            msg = getMessageInfo(projectManageVO,record,projectManageVO.getLastUpdateBy(),workState,true,token);
            List<SysUserEntity> copyUserIList = dictionaryService.queryCcUserIdsByCode("projectManage");
            copyForUserEmails = getCopyForUserEmails(copyUserIList);
            String transpondEmails = transpondEmailService.selectTranspondEmailStr(auditVO.getBusinessId());
            if(!transpondEmails.isEmpty()){
                copyForUserEmails = copyForUserEmails + "," + transpondEmails;
            }
            auditMapper.updateByPrimaryKeySelective(auditVO);
            projectManageMapper.updateByPrimaryKeySelective(projectManageVO);
            migrateCost(projectManageVO,token);
            opportunityAudit(projectManageVO,token);
            approvalService.approved(null,auditVO.getBusinessId());
            //发送邮件
            SysUserEntity finalUser = user;
            String finalCopyForUserEmails = copyForUserEmails;
            String finalTitel = titel;
            String finalMsg = msg;
            CompletableFuture.runAsync(() -> EmailUtils.sentMailByAddressee(finalUser.getEmail(), finalCopyForUserEmails, finalTitel, finalMsg, token));
            //调用通知接口
            Integer finalWorkState = workState;
            Integer finalTodoUser = todoUser;
            CompletableFuture.runAsync(() -> NoticUtils.pushNotic(auditVO.getBusinessId(), approvalVO.getCreateDataTime(), approvalVO.getCreator(), finalWorkState, Constants.PROJECT_TASK_TYPE_ONE, finalTodoUser, token));
        } else {
            if("商务".equals(workFlowResult.getName())){
                user = dictionaryService.queryMenuUserIdsByCode("finance").get(0);
                activitiVO.getCustomParams().put("finance",user.getAccount());
            }else if("财务".equals(workFlowResult.getName())){
                user = dictionaryService.queryMenuUserIdsByCode("afterSales").get(0);
                activitiVO.getCustomParams().put("afterSales",user.getAccount());
            }
            //审批通过（使用动态入参传入下一审批人）
            workFlowService.approvalProcessCustomUserByBusinessId(activitiVO);
            //获取下一节点
            ActivitiVO nextWorkFlowResult = workFlowService.getProcessNodeNameAndCode(activitiVO).getResult();
            if(nextWorkFlowResult.getAssignee().equals(workFlowResult.getAssignee())){
//                approvalService.insertApprovalLog(auditVO.getBusinessId(),"通过", "系统判定跳过",projectManageVO.getProcessComments());
                this.approveProjectInfoOne(projectManageVO,token,true);
            }else {
                workState = 0;
                //交由下一审批人处理
                todoUser = user.getUserId();
                titel = "【系统通知】项目信息初验 - 流程单审批通知";
                String record = "您好，您有一个新的项目信息初验审批需要处理：";
                projectManageVO.setReasonApplication(projectManageVO.getReasonApplicationOne());
               // msg = getMessageInfo(projectManageVO,record,todoUser,workState,true,token);
                approvalService.updateNextApproverByApprovalId(user.getUserId(),approvalVO.getApprovalId());
//                approvalService.insertApprovalLog(auditVO.getBusinessId(),"通过", "项目信息审批",projectManageVO.getProcessComments());
//                String finalCcUser = copyForUserEmails;
//                SysUserEntity finalUser = user;
//                String finalTitel = titel;
//                String finalMsg = msg;
//                CompletableFuture.runAsync(() -> EmailUtils.sentMailByAddressee(finalUser.getEmail(), finalCcUser, finalTitel, finalMsg,token));
                Integer finalWorkState = workState;
                Integer finalTodoUser = todoUser;
                CompletableFuture.runAsync(() -> NoticUtils.pushNotic(auditVO.getBusinessId(), approvalVO.getCreateDataTime(), approvalVO.getCreator(), finalWorkState, Constants.PROJECT_TASK_TYPE_ONE, finalTodoUser, token));
            }
        }
//        if (userId.equals(commercialSpecial.getUserId())) {
//            user = finance;
//            titel = "【系统通知】项目信息初验待处理通知";
//            workState = 0;
//            String record = "您好，您有一个新的项目信息初验待处理：";
//            todoUser = finance.getUserId();
//            msg = getMessageInfo(projectManageVO,record,todoUser,workState,token);
//            approvalService.updateNextApproverByApprovalId(user.getUserId(),approvalVO.getApprovalId());
//        }
//        if (userId.equals(finance.getUserId())) {
//            user = president;
//            titel = "【系统通知】项目信息初验待处理通知";
//            workState = 0;
//            String record = "您好，您有一个新的项目信息初验待处理：";
//            todoUser = president.getUserId();
//            msg = getMessageInfo(projectManageVO,record,todoUser,workState,token);
//            approvalService.updateNextApproverByApprovalId(user.getUserId(),approvalVO.getApprovalId());
//        }
//        if (userId.equals(president.getUserId())) {
//            user = askUser;
//            titel = "【系统通知】项目信息初验通过通知";
//            workState = 1;
//            String record = "您好，您申请的项目信息已经通过：";
//            todoUser = 0;
//            msg = getMessageInfo(projectManageVO,record,projectManageVO.getLastUpdateBy(),workState,token);
//            List<SysUserEntity> copyUserIList = dictionaryService.queryCcUserIdsByCode("projectManage");
//            copyForUserEmails = getCopyForUserEmails(copyUserIList);
//            auditMapper.updateByPrimaryKeySelective(auditVO);
//            projectManageMapper.updateByPrimaryKeySelective(projectManageVO);
//            migrateCost(projectManageVO,token);
//            opportunityAudit(projectManageVO,token);
//            approvalService.approved(null,auditVO.getBusinessId());
//        }
        return true;
    }

    /**
     * 初验驳回
     *
     * @param projectManageVO
     * @return
     */
    public Boolean rejectionProjectInfoOne(SalesProjectManageVO projectManageVO, String token) {
//        Integer userId = AuthUtils.getUserId();
        List<SalesAuditVO> auditVOS = auditMapper.queryAuditInfo(projectManageVO.getProjectManageId(), Constants.PROJECT_MODEL_ID);
        SalesAuditVO auditVO = auditVOS.get(0);
        ActivitiVO activitiVO = new ActivitiVO();
        activitiVO.setAuthorization(AuthUtils.getUserAccount());
        ApprovalVO approvalVO = approvalService.queryApprovalByAppID(auditVO.getBusinessId());
        activitiVO.setBusinessId(approvalVO.getBusinessId());
//        workFlowService.approvalProcessByBusinessId(activitiVO);
        //删除流程实例
        workFlowService.deleteInstance(activitiVO);
//        SysUserEntity commercialSpecial = dictionaryService.queryMenuUserIdsByCode("commercialSpecialist").get(0);
//        SysUserEntity finance = dictionaryService.queryMenuUserIdsByCode("finance").get(0);
//        SysUserEntity president = dictionaryService.queryMenuUserIdsByCode("president").get(0);
//        ResponseAPI<SysUserEntity> res = feginService.searchUserInfoByIds(auditVO.getLastUpdateBy(), token);
//        SysUserEntity user = res.getResult();
        SysUserEntity user;//邮件(下一处理人)
        Integer workState;
        String titel;
        String msg;
        Integer todoUser;//消息
        String copyForUserEmails = null;
        SysUserEntity askUser = feginService.searchUserInfoById(approvalVO.getCreator(), token).getResult();
//        if (userId.equals(commercialSpecial.getUserId())) {
            user = askUser;
            workState = 1;
            titel = "【系统通知】项目信息初验 - 流程单审批驳回通知";
            String record = "您好，您申请的项目信息审批已被驳回：";
            todoUser = askUser.getUserId();
            msg = getMessageInfo(projectManageVO, record, todoUser, workState,false, token);
//            List<SysUserEntity> copyUserIList = dictionaryService.queryCcUserIdsByCode("projectManage");
//            copyForUserEmails = getCopyForUserEmails(copyUserIList);       // 抄送人邮箱
            approvalService.approvalRejection(null,auditVO.getBusinessId());
//            auditVO.setProcessComments(projectManageVO.getProcessComments());
            auditMapper.updateByPrimaryKeySelective(auditVO);
            projectManageMapper.updateByPrimaryKeySelective(projectManageVO);
//        }
//        if (userId.equals(finance.getUserId())) {
//            user = commercialSpecial;
//            workState = 0;
//            titel = "【系统通知】项目信息初验待处理通知";
//            String record = "您好，您有一张新的项目信息审批已被上级驳回：";
//            todoUser = commercialSpecial.getUserId();
//            msg = getMessageInfo(projectManageVO, record, todoUser, workState, token);
//            approvalService.updateNextApproverByApprovalId(user.getUserId(),approvalVO.getApprovalId());
//        }
//        if (userId.equals(president.getUserId())) {
//            user = finance;
//            workState = 0;
//            titel = "【系统通知】项目信息初验待处理通知";
//            String record = "您好，您有一张新的项目信息审批已被上级驳回：";
//            todoUser = finance.getUserId();
//            msg = getMessageInfo(projectManageVO, record, todoUser, workState, token);
//            approvalService.updateNextApproverByApprovalId(user.getUserId(),approvalVO.getApprovalId());
//        }
        //发送邮件
        SysUserEntity finalUser = user;
        String finalTitel = titel;
        String finalMsg = msg;
        CompletableFuture.runAsync(() -> EmailUtils.sentMailByAddressee(finalUser.getEmail(), copyForUserEmails, finalTitel, finalMsg, token));
        //调用通知接口
        Integer finalWorkState = workState;
        Integer finalTodoUser = todoUser;
        CompletableFuture.runAsync(() -> NoticUtils.pushNotic(auditVO.getBusinessId(), auditVO.getLastUpdateTime(), auditVO.getLastUpdateBy(), finalWorkState, Constants.PROJECT_TASK_TYPE_ONE, finalTodoUser, token));
        approvalService.insertApprovalLog(auditVO.getBusinessId(),"驳回", "项目信息审批",projectManageVO.getProcessComments());
        return true;
    }

    /**
     * 终验通过
     *
     * @param projectManageVO
     * @return
     */
    public Boolean approveProjectInfo(SalesProjectManageVO projectManageVO, String token, Boolean auto) {
        ActivitiVO activitiVO = new ActivitiVO();
        activitiVO.setAuthorization(AuthUtils.getUserAccount());
        ApprovalVO approvalVO = approvalService.queryApprovalByAppID(projectManageVO.getBusinessId());
        activitiVO.setBusinessId(approvalVO.getBusinessId());
        //获取当前所处节点
        ActivitiVO workFlowResult = workFlowService.getProcessNodeNameAndCode(activitiVO).getResult();
        SysUserEntity user = null;//邮件(下一处理人)
        Integer workState;
        String titel;
        String msg;
        Integer todoUser;//消息
        String copyForUserEmails = null;
        SysUserEntity askUser = feginService.searchUserInfoById(approvalVO.getCreator(), token).getResult();
        //记录审批日志
        if(auto){
            approvalService.insertApprovalLog(projectManageVO.getBusinessId(),"通过", "系统判定跳过",projectManageVO.getProcessComments());
        }else {
            approvalService.insertApprovalLog(projectManageVO.getBusinessId(),"通过", "项目信息审批",projectManageVO.getProcessComments());
        }
        if ("商务".equals(workFlowResult.getName())){
            // 审批通过
            workFlowService.approvalProcessByBusinessId(activitiVO);
            user = askUser;
            titel = "【系统通知】项目信息终验 - 流程单审批通过通知";
            workState = 1;
            String record = "您好，您申请的项目信息审批已经通过：";
            todoUser = 0;
            msg = getMessageInfo(projectManageVO,record,projectManageVO.getLastUpdateBy(),workState,true,token);
            List<SysUserEntity> copyUserIList = dictionaryService.queryCcUserIdsByCode("projectManage");
            copyForUserEmails = getCopyForUserEmails(copyUserIList);
            String transpondEmails = transpondEmailService.selectTranspondEmailStr(projectManageVO.getBusinessId());
            if(!transpondEmails.isEmpty()){
                copyForUserEmails = copyForUserEmails + "," + transpondEmails;
            }
            //项目无阶段
//            SalesStageVO stageVO = stageMapper.queryStageInfo(projectManageVO.getProjectManageId(), Constants.PROJECT_MODEL_ID).get(0);
//            stageMapper.updateByPrimaryKeySelective(stageVO);
            projectManageMapper.updateByPrimaryKeySelective(projectManageVO);
//            migrateCost(projectManageVO,token);
//            opportunityAudit(projectManageVO,token);
            approvalService.approved(null,projectManageVO.getBusinessId());
            //发送邮件
            SysUserEntity finalUser = user;
            String finalCopyForUserEmails = copyForUserEmails;
            String finalTitel = titel;
            String finalMsg = msg;
            CompletableFuture.runAsync(() -> EmailUtils.sentMailByAddressee(finalUser.getEmail(), finalCopyForUserEmails, finalTitel, finalMsg, token));
            //调用通知接口
            Integer finalWorkState = workState;
            Integer finalTodoUser = todoUser;
            CompletableFuture.runAsync(() -> NoticUtils.pushNotic(projectManageVO.getBusinessId(), approvalVO.getCreateDataTime(), approvalVO.getCreator(),  finalWorkState, Constants.PROJECT_TASK_TYPE, finalTodoUser, token));
        }
//        else {
//            if("商务".equals(workFlowResult.getName())){
//                user = dictionaryService.queryMenuUserIdsByCode("finance").get(0);
//                activitiVO.getCustomParams().put("finance",user.getAccount());
//            }else if("财务".equals(workFlowResult.getName())){
//                user = dictionaryService.queryMenuUserIdsByCode("president").get(0);
//                activitiVO.getCustomParams().put("president",user.getAccount());
//            }
//            //审批通过（使用动态入参传入下一审批人）
//            workFlowService.approvalProcessCustomUserByBusinessId(activitiVO);
//            //获取下一节点
//            ActivitiVO nextWorkFlowResult = workFlowService.getProcessNodeNameAndCode(activitiVO).getResult();
//            if(nextWorkFlowResult.getAssignee().equals(workFlowResult.getAssignee())){
//                this.approveProjectInfo(projectManageVO,token,true);
//            }else {
//                workState = 0;
//                //交由下一审批人处理
//                todoUser = user.getUserId();
////                titel = "【系统通知】项目信息终验 - 流程单审批通知";
////                String record = "您好，您有一个新的项目信息终验审批需要处理：";
////                msg = getMessageInfo(projectManageVO,record,todoUser,workState,true,token);
//                approvalService.updateNextApproverByApprovalId(user.getUserId(),approvalVO.getApprovalId());
////                approvalService.insertApprovalLog(projectManageVO.getBusinessId(),"通过", "项目信息审批",projectManageVO.getProcessComments());
//                String finalCcUser = copyForUserEmails;
//                SysUserEntity finalUser = user;
////                String finalTitel = titel;
////                String finalMsg = msg;
////                CompletableFuture.runAsync(() -> EmailUtils.sentMailByAddressee(finalUser.getEmail(), finalCcUser, finalTitel, finalMsg,token));
//                Integer finalWorkState = workState;
//                Integer finalTodoUser = todoUser;
//                CompletableFuture.runAsync(() -> NoticUtils.pushNotic(projectManageVO.getBusinessId(), approvalVO.getCreateDataTime(), approvalVO.getCreator(),  finalWorkState, Constants.PROJECT_TASK_TYPE, finalTodoUser, token));
//            }
//        }
        return true;
    }

    /**
     * 终验驳回
     *
     * @param projectManageVO
     * @return
     */
    public Boolean rejectionProjectInfo(SalesProjectManageVO projectManageVO, String token) {
//        Integer userId = AuthUtils.getUserId();
        ActivitiVO activitiVO = new ActivitiVO();
        activitiVO.setAuthorization(AuthUtils.getUserAccount());
        ApprovalVO approvalVO = approvalService.queryApprovalByAppID(projectManageVO.getBusinessId());
        activitiVO.setBusinessId(approvalVO.getBusinessId());
        //删除流程实例
        workFlowService.deleteInstance(activitiVO);
//        workFlowService.approvalProcessByBusinessId(activitiVO);
//        SysUserEntity commercialSpecial = dictionaryService.queryMenuUserIdsByCode("commercialSpecialist").get(0);
//        SysUserEntity finance = dictionaryService.queryMenuUserIdsByCode("finance").get(0);
//        SysUserEntity president = dictionaryService.queryMenuUserIdsByCode("president").get(0);
        SysUserEntity user;//邮件(下一处理人)
        Integer workState;
        String titel;
        String msg;
        Integer todoUser;//消息
        String copyForUserEmails = null;
        SysUserEntity askUser = feginService.searchUserInfoById(approvalVO.getCreator(), token).getResult();
//        if (userId.equals(commercialSpecial.getUserId())) {
            user = askUser;
            workState = 1;
            titel = "【系统通知】项目信息终验 - 流程单审批驳回通知";
            String record = "您好，您申请的项目信息审批已被驳回：";
            todoUser = askUser.getUserId();
            msg = getMessageInfo(projectManageVO, record, todoUser, workState,false, token);
//            List<SysUserEntity> copyUserIList = dictionaryService.queryCcUserIdsByCode("projectManage");
//            copyForUserEmails = getCopyForUserEmails(copyUserIList);       // 抄送人邮箱
            projectManageMapper.updateByPrimaryKeySelective(projectManageVO);
            approvalService.approvalRejection(null,projectManageVO.getBusinessId());
//        }
//        if (userId.equals(finance.getUserId())) {
//            user = commercialSpecial;
//            workState = 0;
//            titel = "【系统通知】项目信息初验待处理通知";
//            String record = "您好，您有一张新的项目信息审批已被上级驳回：";
//            todoUser = commercialSpecial.getUserId();
//            msg = getMessageInfo(projectManageVO, record, todoUser, workState, token);
//            approvalService.updateNextApproverByApprovalId(user.getUserId(),approvalVO.getApprovalId());
//        }
//        if (userId.equals(president.getUserId())) {
//            user = finance;
//            workState = 0;
//            titel = "【系统通知】项目信息初验待处理通知";
//            String record = "您好，您有一张新的项目信息审批已被上级驳回：";
//            todoUser = finance.getUserId();
//            msg = getMessageInfo(projectManageVO, record, todoUser, workState, token);
//            approvalService.updateNextApproverByApprovalId(user.getUserId(),approvalVO.getApprovalId());
//        }
        //发送邮件
        SysUserEntity finalUser = user;
        String finalTitel = titel;
        String finalMsg = msg;
        CompletableFuture.runAsync(() -> EmailUtils.sentMailByAddressee(finalUser.getEmail(), copyForUserEmails, finalTitel, finalMsg, token));
        //调用通知接口
        Integer finalWorkState = workState;
        Integer finalTodoUser = todoUser;
        CompletableFuture.runAsync(() -> NoticUtils.pushNotic(projectManageVO.getBusinessId(), projectManageVO.getLastUpdateTime(),  projectManageVO.getLastUpdateBy(),finalWorkState, Constants.PROJECT_TASK_TYPE, finalTodoUser, token));
        approvalService.insertApprovalLog(projectManageVO.getBusinessId(),"驳回", "项目信息审批",projectManageVO.getProcessComments());
        return true;
    }

    /**
     * 根据工作流ID获取终验信息
     *
     * @param workId
     * @return
     */
    public SalesProjectManageVO queryProjectApprovalByWorkId(Integer workId) {
        SalesProjectManageVO projectManageVO = projectManageMapper.queryProjectApprovalByWorkId(workId);
        projectManageVO.setSenderList(transpondEmailService.queryTranspondByApprovalId(projectManageVO.getBusinessId()));
        return projectManageVO;
    }

    /**
     * 根据工作流ID获取初验信息
     *
     * @param workId
     * @return
     */
    @Override
    public SalesProjectManageVO queryProjectApprovalOneByWorkId(Integer workId,String token) {
        SalesAuditVO auditVO = auditMapper.queryAuditByWorkId(workId);
        SalesProjectManageVO projectManageVO = this.queryProjectInfoById(auditVO.getSalesRelationId(),token);
        projectManageVO.setApproveState(auditVO.getAuditState());
        projectManageVO.setProcessComments(auditVO.getProcessComments());
        projectManageVO.setReasonApplicationOne(auditVO.getReasonApplication());
        projectManageVO.setLastUpdateTime(auditVO.getLastUpdateTime());
        projectManageVO.setLastUpdateTimeOne(auditVO.getLastUpdateTime());
        return projectManageVO;
    }

    @Override
    public SalesProjectManageVO queryHistoryProjectApprovalByApprovalId(Integer workId) {
        SalesProjectManageVO projectManageVO = projectManageMapper.queryHistoryProjectApprovalByApprovalId(workId);
        if (Objects.isNull(projectManageVO)) {
            return queryProjectApprovalByWorkId(workId);
        }
        projectManageVO.setSenderList(transpondEmailService.queryTranspondByApprovalId(workId));
        return projectManageVO;
    }

    @Override
    public SalesProjectManageVO queryHistoryProjectApprovalOneByApprovalId(Integer workId,String token) {
        SalesAuditVO auditVO = auditMapper.queryHistoryAuditInfoByApprovalId(workId);
        SalesProjectManageVO projectManageVO = projectManageMapper.queryHistoryProjectApprovalOneByApprovalId(workId);
        if (Objects.isNull(auditVO) || Objects.isNull(projectManageVO)) {
            return queryProjectApprovalOneByWorkId(workId,token);
        }
        projectManageVO.setApproveState(auditVO.getAuditState());
        projectManageVO.setProcessComments(auditVO.getProcessComments());
        projectManageVO.setReasonApplicationOne(auditVO.getReasonApplication());
        projectManageVO.setSenderList(transpondEmailService.queryTranspondByApprovalId(auditVO.getBusinessId()));
        return projectManageVO;
    }

    @Override
    public PageUtil<SalesProjectManageVO> queryTodoProjectsByPage(IPage<SalesProjectManageVO> page, SalesProjectManageVO projectManageVO) {
        ActivitiVO activitiVO = new ActivitiVO();
        activitiVO.setAuthorization(AuthUtils.getUserAccount());
        activitiVO.setProcessName("项目信息终验流程");
        activitiVO.setProcessCode("project_approval");
        ResponseAPI<List<ActivitiVO>> workFlowVoResponseAPI = workFlowService.getTasksByAuthorization(activitiVO);
        List<ActivitiVO> activitiVOS = workFlowVoResponseAPI.getResult();
        if (activitiVOS.size() == 0) {
            return new PageUtil(new PageDTO());
        } else {
            if (projectManageVO.getOrderByProp() != null) {
                projectManageVO.setOrderByProp(StringUtils.camelToUnderline(projectManageVO.getOrderByProp()));
            }
            return new PageUtil(projectManageMapper.queryTodoProjectsByPage(page, projectManageVO, activitiVOS));
        }
    }

    /**
     * 通过项目ID获取项目信息
     *
     * @param projectID
     * @return
     */
    public SalesProjectManageVO queryProjectByID(Integer projectID) {
        //获取项目主信息（项目、机会点、客户等）
        SalesProjectManageVO projectManage = projectManageMapper.queryProjectByID(projectID);
        //获取文件
        projectManage.setDocuments(projectManageMapper.selectDocymentsByprojectId(projectID));
        //获取全部联系人contacts
        projectManage.setContacts(projectManageMapper.selectContactsByprojectId(projectID));

        //获取合同信息 contractInfo
        List<ContractInfoVO> contractInfoVOS = contractInfoService.queryContractInfoByProjectId(projectManage.getProjectManageId(),null);
        projectManage.setContractInfos(contractInfoVOS);
        projectManage.getAllThings().addAll(contractInfoVOS);
        //获取回款计划
        List<ContractInfoVO> bmpList = projectManageMapper.getProjectAllBackmoneyPlan(projectID);
        for (ContractInfoVO contractInfoVO : bmpList) {
            if (contractInfoVO.getBackMoneyPlanList().size() >0){
                for (BackMoneyPlanVo backMoneyPlanVo : contractInfoVO.getBackMoneyPlanList()) {
                    HashMap<String, Object> hashMap = new HashMap<>();
                    hashMap.put("bmpId",backMoneyPlanVo.getBmpId());
                    hashMap.put("creator",backMoneyPlanVo.getCreator());
                    hashMap.put("createDataTime",backMoneyPlanVo.getCreateDataTime());
                    hashMap.put("contractTopic",contractInfoVO.getContractTopic());
                    hashMap.put("bmpPeriod",backMoneyPlanVo.getBmpPeriod());
                    hashMap.put("bmpDate",backMoneyPlanVo.getBmpDate());
                    hashMap.put("bmpMoney",backMoneyPlanVo.getBmpMoney());
                    hashMap.put("flushMoney",backMoneyPlanVo.getFlushMoney());
                    hashMap.put("liableId",backMoneyPlanVo.getLiableId());
                    hashMap.put("bmpRemarks",backMoneyPlanVo.getBmpRemarks());

                    //合同甲方
                    hashMap.put("contractLessorId",contractInfoVO.getContractLessorId());
                    Map<String, String> allPageShowMoney= brAndBmrService.getAllPageShowMoneybyBmpId(backMoneyPlanVo.getBmpId());
                    hashMap.put("allPageShowMoney",allPageShowMoney);
                    hashMap.put("approvalStatus",contractInfoVO.getApprovalStatus());
                    projectManage.getAllThings().add(hashMap);
                }
            }
        }
        //获取开票申请
        List<ContractInfoVO> projectAllBillingRecord = brAndBmrService.getProjectAllBillingRecord(projectID, 0);
        for (ContractInfoVO contractInfoVO : projectAllBillingRecord) {
            if (contractInfoVO.getBillingRecordVoList().size() > 0){
                for (BillingRecordVo billingRecordVo : contractInfoVO.getBillingRecordVoList()) {
                    HashMap<String, Object> map = new HashMap<>();
                    map.put("contractLessorId",contractInfoVO.getContractLessorId());
                    map.put("contractTopic",contractInfoVO.getContractTopic());
                    billingRecordVo.setAllInfo(map);
                    projectManage.getAllThings().add(billingRecordVo);
                }
            }
        }
        //获取开票记录
        List<ContractInfoVO> projectAllBillingRecord1 = brAndBmrService.getProjectAllBillingRecord(projectID, 1);
        for (ContractInfoVO contractInfoVO : projectAllBillingRecord1) {
            if (contractInfoVO.getBillingRecordVoList().size() > 0){
                for (BillingRecordVo billingRecordVo : contractInfoVO.getBillingRecordVoList()) {
                    HashMap<String, Object> map = new HashMap<>();
                    map.put("contractLessorId",contractInfoVO.getContractLessorId());
                    map.put("contractTopic",contractInfoVO.getContractTopic());
                    billingRecordVo.setAllInfo(map);
                    projectManage.getAllThings().add(billingRecordVo);
                }
            }
        }
        //获取回款记录
        List<ContractInfoVO> projectAllBackMoneyRecord = brAndBmrService.getProjectAllBackMoneyRecord(projectID);
        for (ContractInfoVO contractInfoVO : projectAllBackMoneyRecord) {
            if (contractInfoVO.getBackMoneyRecordVoList().size() > 0){
                for (BackMoneyRecordVo backMoneyRecordVo : contractInfoVO.getBackMoneyRecordVoList()) {
                    HashMap<String, Object> map = new HashMap<>();
                    map.put("contractLessorId",contractInfoVO.getContractLessorId());
                    map.put("contractTopic",contractInfoVO.getContractTopic());
                    backMoneyRecordVo.setAllInfo(map);
                    projectManage.getAllThings().add(backMoneyRecordVo);
                }
            }
        }
        //获取全部退款信息
//        List<RefundRecordsVO> recordsVOS = refundRecordsMapper.selectRefundByProjectId(projectID);
//        projectManage.setRefundRecords(recordsVOS);
//        projectManage.getAllThings().addAll(recordsVOS);
        //获取订单信息
        List<PurchaseOrderVO> purchaseOrderVOS = purchaseOrdeService.queryPurchaseOrdersByProjectId(projectManage.getProjectManageId());

        for (PurchaseOrderVO pvo:purchaseOrderVOS) {
            List<Integer> ids = new ArrayList<>();
            ids.add(pvo.getPurchaseId());
            // 收票记录
            pvo.setReceiptRecords(receiptRecordsMapper.getReceiptRecordsByPurchaseOrderIds(ids));
            // 付款记录
            pvo.setPaymentRecords(paymentRecordsMapper.getPayRecordsByPurchaseOrderIds(ids));
            // 付款申请
            pvo.setPaymentRequests(paymentRequestMapper.getPayRequestByPurchaseOrderIds(ids));
            // 退款记录
            List<RefundRecordsVO> refundRecordsByPurchaseIds = refundRecordsMapper.getRefundRecordsByPurchaseIds(ids);
            for (RefundRecordsVO refundRecordsByPurchaseId : refundRecordsByPurchaseIds) {
                String stringBuilder = transpondEmailService.selectTranspondNameStr(refundRecordsByPurchaseId.getApprovalId());
                if (stringBuilder != null || stringBuilder.length() != 0){
                    refundRecordsByPurchaseId.setTranspondUseListStr(stringBuilder);
                }
            }
            pvo.setRefundRecords(refundRecordsByPurchaseIds);
        }
        projectManage.setPurchaseOrders(purchaseOrderVOS);
        projectManage.getAllThings().addAll(purchaseOrderVOS);

        //内部采购
        List<PurchaseOrderVO> inPurchaseOrderVOS = internalPurchaseService.queryPurchaseOrdersByProjectId(projectManage.getProjectManageId());
        projectManage.getAllThings().addAll(inPurchaseOrderVOS);
        projectManage.setInPurchaseOrders(inPurchaseOrderVOS);

        if(purchaseOrderVOS != null && purchaseOrderVOS.size()>0){
            List<Integer> list  = new ArrayList<>();
            for (PurchaseOrderVO purchaseOrderVO: purchaseOrderVOS) {
                list.add(purchaseOrderVO.getPurchaseId());
            }
            List<PaymentPlan> paymentPlans = paymentPlanMapper.getPayPlanListBypurchaseOrderIds(list);
            List<PaymentRecords> paymentRecords = paymentRecordsMapper.getPayRecordsByPurchaseOrderIds(list);
            List<ReceiptRecords> receiptRecords = receiptRecordsMapper.getReceiptRecordsByPurchaseOrderIds(list);

            List<PaymentRequest> paymentRequests = paymentRequestMapper.getPayRequestByPurchaseOrderIds(list);

            List<RefundRecordsVO> recordsVOS = refundRecordsMapper.getRefundRecordsByPurchaseIds(list);
            for (RefundRecordsVO refundRecordsByPurchaseId : recordsVOS) {
                String stringBuilder = transpondEmailService.selectTranspondNameStr(refundRecordsByPurchaseId.getApprovalId());
                if (stringBuilder != null || stringBuilder.length() != 0){
                    refundRecordsByPurchaseId.setTranspondUseListStr(stringBuilder);
                }
            }
            // 付款计划
            projectManage.setPaymentPlans(paymentPlans);
            projectManage.setPaymentRecords(paymentRecords);
            projectManage.setReceiptRecords(receiptRecords);
            projectManage.setPaymentRequests(paymentRequests);
            projectManage.setRefundRecords(recordsVOS);
            projectManage.getAllThings().addAll(paymentRecords);
            projectManage.getAllThings().addAll(receiptRecords);
            projectManage.getAllThings().addAll(paymentRequests);
            projectManage.getAllThings().addAll(paymentPlans);
            projectManage.getAllThings().addAll(recordsVOS);
        }

        //获取跟单视图回款、开票、已回金额汇总显示
        ShowMoneyVo sumAllMoneyShow = brAndBmrMapper.getSumAllMoneyShow(projectID);
        if (sumAllMoneyShow == null){
            ShowMoneyVo showMoneyVo = new ShowMoneyVo();
            projectManage.setShowMoneyVo(showMoneyVo);
        }else{
            projectManage.setShowMoneyVo(sumAllMoneyShow);
        }
        return projectManage;
    }

    /**
     * 获取全部项目信息
     *
     * @return
     */
    public List<SalesProjectManageVO> queryProjects(String source) {
        return projectManageMapper.queryProjects(source);
    }

    @Override
    public boolean changeStage(SalesStageVO salesStageVO) {
        List<SalesStageVO> stageVOList = stageMapper.queryStageInfo(salesStageVO.getSalesRelationId(), Constants.PROJECT_MODEL_ID);
        SalesStageVO stageVO = stageVOList.get(0);
        if (Objects.equals(stageVO.getStageStateId(), salesStageVO.getStageStateId())) {
            return false;
        }
        salesStageVO.setStageClass(Constants.PROJECT_MODEL_ID);
        addStageInfo(salesStageVO);
        return true;
    }

    /**
     * 根据项目id 获取全部回款计划
     * @param id
     * @return
     */
    @Override
    public List<ContractInfoVO> getProjectAllBackmoneyPlan(Integer id) {
        List<ContractInfoVO> bmpList = projectManageMapper.getProjectAllBackmoneyPlan(id);
        for (ContractInfoVO contractInfoVO : bmpList) {
            if (contractInfoVO.getBackMoneyPlanList().size() >0){
                for (BackMoneyPlanVo backMoneyPlanVo : contractInfoVO.getBackMoneyPlanList()) {
                    Map<String, String> allPageShowMoney= brAndBmrService.getAllPageShowMoneybyBmpId(backMoneyPlanVo.getBmpId());
                    backMoneyPlanVo.setAllPageShowMoney(allPageShowMoney);
                }
            }
        }
        return bmpList;
    }

    /**
     * 根据客户id 获取全部回款计划
     * @param customerId
     * @return
     */
    @Override
    public List<ContractInfoVO> getProjectAllBackmoneyPlanByCustomerId(Integer customerId) {
        List<ContractInfoVO> bmpList = projectManageMapper.getProjectAllBackmoneyPlanByCustomerId(customerId);
        for (ContractInfoVO contractInfoVO : bmpList) {
            if (contractInfoVO.getBackMoneyPlanList().size() >0){
                for (BackMoneyPlanVo backMoneyPlanVo : contractInfoVO.getBackMoneyPlanList()) {
                    Map<String, String> allPageShowMoney= brAndBmrService.getAllPageShowMoneybyBmpId(backMoneyPlanVo.getBmpId());
                    backMoneyPlanVo.setAllPageShowMoney(allPageShowMoney);
                }
            }
        }
        return bmpList;
    }

    @Override
    public ActivitiVO updateManagerSubmit(Integer projectId,ProjectUpdateInfoVO reasonVO, String token) {
        SalesProjectManageVO projectManageVO = projectManageMapper.selectByPrimaryKey(projectId);
        ActivitiVO activitiVO = new ActivitiVO();
        activitiVO.setAuthorization(AuthUtils.getUserAccount());
        activitiVO.setProcessName("项目流程变更测试");
        activitiVO.setProcessCode("project_change_process1");
        activitiVO.setNextNodeParams("commercialSpecialist");
        //商务信息
        SysUserEntity commercialSpecial = dictionaryService.queryMenuUserIdsByCode("commercialSpecialist").get(0);
        activitiVO.setNextNodeAssignee(commercialSpecial.getAccount());

        //售后信息
        SysUserEntity financeManager = dictionaryService.queryMenuUserIdsByCode("finance").get(0);
        //会计信息
        SysUserEntity afterSalesManager = dictionaryService.queryMenuUserIdsByCode("afterSales").get(0);
        //总经理信息
        SysUserEntity generalManager = dictionaryService.queryMenuUserIdsByCode("president").get(0);
        ResponseAPI<ActivitiVO> responseAPI = workFlowService.startMaxVersionProcessByDesignCodeCustomParams(activitiVO);
        ApprovalVO approval = approvalService.initApprovalAndLog(responseAPI.getResult().getBusinessId(),
                Constants.UPDATE_MANAGER_TYPE, reasonVO.getReason(), "",commercialSpecial.getUserId(),"");
        // 将审批信息和项目id建立关系
        projectManageMapper.addProjectAndBusiness(responseAPI.getResult().getBusinessId(),projectId,reasonVO.getReason());
        this.updateStatusAfterSubmit(responseAPI.getResult().getBusinessId(),projectId,token);
        projectManageMapper.updateProjectStatus(projectId,true,0);
        if (commercialSpecial.getUserId().equals(AuthUtils.getUserId())){
            //跳过第一步审批
            this.updateManagerApprove(projectId,token,true);
        }else{
            projectManageVO.setApprovalId(approval.getApprovalId());
            projectManageVO.setCreator(AuthUtils.getUserId());
            sendEmailAndPushNotice(commercialSpecial,projectManageVO,token);
        }
        return responseAPI.getResult();

    }

    @Override
    public Boolean updateManagerApprove(Integer projectId, String token, boolean b) {
        SalesProjectManageVO projectManageVO = projectManageMapper.selectByPrimaryKey(projectId);
        SalesProjectManageVO projectAndBusinessInfo = projectManageMapper.queryProjectAndBusinessInfo(projectId);
        projectManageVO.setApprovalId(projectAndBusinessInfo.getApprovalId());
        ActivitiVO activitiVO = new ActivitiVO();
        activitiVO.setAuthorization(AuthUtils.getUserAccount());
        activitiVO.setBusinessId(projectAndBusinessInfo.getBusinessId());
        //获取当前所处节点
        ResponseAPI<ActivitiVO> processNodeNameAndCode = workFlowService.getProcessNodeNameAndCode(activitiVO);
        //记录审批日志
        if(b){
            approvalService.insertApprovalLog(projectManageVO.getApprovalId(),"通过",
                    "系统判定跳过",null);
        }else {
            //记录日志
            approvalService.insertApprovalLog(projectManageVO.getApprovalId(),"通过",
                    "",null);
        }
        if ("售后".equals(processNodeNameAndCode.getResult().getName())){
            // 审批通过
            workFlowService.approvalProcessByBusinessId(activitiVO);
            approvalService.approved(null,projectManageVO.getApprovalId());
            projectManageMapper.updateProjectStatus(projectId,false,1);
            // 审批通过后依据日志表去修改对应业务数据
            this.updateFinalBusinessToDB(projectId,token);
            // 通过后将本次变更内容缓存清空
            this.deleteCacheInfo(projectId, token);
            this.updateLastTimeAfterApprove(projectId);
            CompletableFuture.runAsync(() -> NoticUtils.pushNotic(projectManageVO.getApprovalId(),  new Timestamp(System.currentTimeMillis()), projectManageVO.getCreator(),
                    Constants.WORK_STATE_STOP,Constants.UPDATE_MANAGER_TYPE,-1,token));
        }else{
            SysUserEntity nowApprover = null;
            if ("商务".equals(processNodeNameAndCode.getResult().getName())){
                //会计信息
                nowApprover = dictionaryService.queryMenuUserIdsByCode( "finance").get(0);
                activitiVO.getCustomParams().put("finance",nowApprover.getAccount());
            }else if("会计".equals(processNodeNameAndCode.getResult().getName())){
                ///售后信息
                nowApprover = dictionaryService.queryMenuUserIdsByCode( "afterSales").get(0);
                activitiVO.getCustomParams().put("afterSales",nowApprover.getAccount());
            }

            workFlowService.approvalProcessCustomUserByBusinessId(activitiVO);
            //获取下一节点
            ResponseAPI<ActivitiVO> nextProcessNodeNameAndCode = workFlowService.getProcessNodeNameAndCode(activitiVO);
            if(nextProcessNodeNameAndCode.getResult().getAssignee().equals(processNodeNameAndCode.getResult().getAssignee())){ //记录日志
                this.updateManagerApprove(projectId,token,true);
            }else {
                approvalService.updateNextApproverByApprovalId(nowApprover.getUserId(), projectManageVO.getApprovalId());
                projectManageVO.setCreator(AuthUtils.getUserId());
                sendEmailAndPushNotice(nowApprover,projectManageVO,token);
            }
        }
        return true;
    }

    @Override
    public Boolean updateManagerReject(Integer projectId, String token) {
        SalesProjectManageVO projectManageVO = projectManageMapper.selectByPrimaryKey(projectId);
        SalesProjectManageVO projectAndBusinessInfo = projectManageMapper.queryProjectAndBusinessInfo(projectId);
        projectManageVO.setApprovalId(projectAndBusinessInfo.getApprovalId());
        projectManageVO.setCreator(projectAndBusinessInfo.getCreator());
        ActivitiVO activitiVO = new ActivitiVO();
        activitiVO.setAuthorization(AuthUtils.getUserAccount());
        activitiVO.setBusinessId(projectAndBusinessInfo.getBusinessId());
        // 删除实例，驳回至起点
        workFlowService.deleteInstance(activitiVO);
        // 将本次变更的内容设置为可编辑状态
        this.deleteUpdateInfoAfterRejection(projectId);
        projectManageMapper.updateProjectStatus(projectId,false,2);
        rjSendEmailAndPushNotice(projectManageVO,token);
        approvalService.insertApprovalLog(projectManageVO.getApprovalId(),"驳回",
                "",null);
        return approvalService.approvalRejection(projectAndBusinessInfo.getBusinessId(),projectManageVO.getApprovalId());
    }

    @Override
    public List<ProjectUpdateInfoVO> queryUpdateInfoByApproveId(Integer approveId) {
        List<ProjectUpdateInfoVO> projectUpdateInfoVOS = projectManageMapper.queryUpdateInfoByApproveId(approveId);
        projectUpdateInfoVOS = projectUpdateInfoVOS.stream().filter(item ->"update".equals(item.getOperateType())).collect(Collectors.toList());
        return projectUpdateInfoVOS;
    }


    @Override
    public List<ProjectUpdateInfoVO> queryUpdateInfoById(Integer projectManageId) {
        List<ProjectUpdateInfoVO> projectUpdateInfoVOS = projectManageMapper.queryUpdateInfoById(projectManageId);
        projectUpdateInfoVOS = projectUpdateInfoVOS.stream().filter(item ->"update".equals(item.getOperateType())).collect(Collectors.toList());
        return projectUpdateInfoVOS;
    }

    @Override
    public List<ProjectUpdateInfoVO> queryUpdateInfoOnLineById(Integer projectManageId) {
        return projectManageMapper.queryUpdateInfoOnLineById(projectManageId);
    }

    @Override
    public void updateFinalBusinessToDB(Integer projectId, String token) {
        SimpleDateFormat formatter = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss");
        List<ProjectUpdateInfoVO> updateInfos = projectManageMapper.queryNeedUpdateInfoById(projectId);
        // 需要筛选出本次更新入库的数据集
        Map<String,List <ProjectUpdateInfoVO>> updateInfosMap = updateInfos.stream().collect(Collectors.groupingBy(ProjectUpdateInfoVO::getOperateType));
        List<ProjectUpdateInfoVO> updateInfoList = updateInfosMap.get("update");
        List<ProjectUpdateInfoVO> insertInfoList = updateInfosMap.get("insert");
        List<ProjectUpdateInfoVO> deleteInfoList = updateInfosMap.get("delete");
        if(!CollectionUtils.isEmpty(updateInfoList)){
            for (ProjectUpdateInfoVO updateInfo : updateInfoList) {
                String updateSql = "update" + " " + updateInfo.getTableName() + " " + "set"+" " + updateInfo.getColumnName() +"="+"'"+updateInfo.getNewValue()+"' "
                        +"where "+" "+updateInfo.getPrimaryKey() +"="+updateInfo.getBusinessId();
                projectManageMapper.updateInfoToDb(updateSql);
            }
        }
        if(!CollectionUtils.isEmpty(insertInfoList)){
            for (ProjectUpdateInfoVO insertInfo : insertInfoList) {
                StringBuffer columnStr = new StringBuffer();
                StringBuffer valueStr = new StringBuffer();
                if(StringUtils.isNotEmpty(insertInfo.getItemName1()) ){
                    columnStr.append(insertInfo.getItemName1()).append(",");
                    if("".equals(insertInfo.getItemValue1()) || insertInfo.getItemValue1() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue1()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName2()) ){
                    columnStr.append(insertInfo.getItemName2()).append(",");
                    if("".equals(insertInfo.getItemValue2()) || insertInfo.getItemValue2() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue2()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName3()) ){
                    columnStr.append(insertInfo.getItemName3()).append(",");
                    if("".equals(insertInfo.getItemValue3()) || insertInfo.getItemValue3() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue3()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName4()) ){
                    columnStr.append(insertInfo.getItemName4()).append(",");
                    if("".equals(insertInfo.getItemValue4()) || insertInfo.getItemValue4() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue4()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName5()) ){
                    columnStr.append(insertInfo.getItemName5()).append(",");
                    if("".equals(insertInfo.getItemValue5()) || insertInfo.getItemValue5() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue5()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName6()) ){
                    columnStr.append(insertInfo.getItemName6()).append(",");
                    if("".equals(insertInfo.getItemValue6()) || insertInfo.getItemValue6() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue6()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName7()) ){
                    columnStr.append(insertInfo.getItemName7()).append(",");
                    if("".equals(insertInfo.getItemValue7()) || insertInfo.getItemValue7() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue7()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName8()) ){
                    columnStr.append(insertInfo.getItemName8()).append(",");
                    if("".equals(insertInfo.getItemValue8()) || insertInfo.getItemValue8() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue8()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName9()) ){
                    columnStr.append(insertInfo.getItemName9()).append(",");
                    if("".equals(insertInfo.getItemValue9()) || insertInfo.getItemValue9() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue9()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName10()) ){
                    columnStr.append(insertInfo.getItemName10()).append(",");
                    if("".equals(insertInfo.getItemValue10()) || insertInfo.getItemValue10() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue10()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName11()) ){
                    columnStr.append(insertInfo.getItemName11()).append(",");
                    if("".equals(insertInfo.getItemValue11()) || insertInfo.getItemValue11() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue11()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName12()) ){
                    columnStr.append(insertInfo.getItemName12()).append(",");
                    if("".equals(insertInfo.getItemValue12()) || insertInfo.getItemValue12() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue12()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName13()) ){
                    columnStr.append(insertInfo.getItemName13()).append(",");
                    if("".equals(insertInfo.getItemValue13()) || insertInfo.getItemValue13() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue13()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName14()) ){
                    columnStr.append(insertInfo.getItemName14()).append(",");
                    if("".equals(insertInfo.getItemValue14()) || insertInfo.getItemValue14() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue14()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName15()) ){
                    columnStr.append(insertInfo.getItemName15()).append(",");
                    if("".equals(insertInfo.getItemValue15()) || insertInfo.getItemValue15() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue15()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName16()) ){
                    columnStr.append(insertInfo.getItemName16()).append(",");
                    if("".equals(insertInfo.getItemValue16()) || insertInfo.getItemValue16() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue16()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName17()) ){
                    columnStr.append(insertInfo.getItemName17()).append(",");
                    if("".equals(insertInfo.getItemValue17()) || insertInfo.getItemValue17() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue17()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName18()) ){
                    columnStr.append(insertInfo.getItemName18()).append(",");
                    if("".equals(insertInfo.getItemValue18()) || insertInfo.getItemValue18() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue18()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName19()) ){
                    columnStr.append(insertInfo.getItemName19()).append(",");
                    if("".equals(insertInfo.getItemValue19()) || insertInfo.getItemValue19() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue19()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName20()) ){
                    columnStr.append(insertInfo.getItemName20()).append(",");
                    if("".equals(insertInfo.getItemValue20()) || insertInfo.getItemValue20() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue20()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName21()) ){
                    columnStr.append(insertInfo.getItemName21()).append(",");
                    if("".equals(insertInfo.getItemValue21()) || insertInfo.getItemValue21() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue21()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName22()) ){
                    columnStr.append(insertInfo.getItemName22()).append(",");
                    if("".equals(insertInfo.getItemValue22()) || insertInfo.getItemValue22() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue22()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName23()) ){
                    columnStr.append(insertInfo.getItemName23()).append(",");
                    if("".equals(insertInfo.getItemValue23()) || insertInfo.getItemValue23() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue23()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName24()) ){
                    columnStr.append(insertInfo.getItemName24()).append(",");
                    if("".equals(insertInfo.getItemValue24()) || insertInfo.getItemValue24() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue24()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName25()) ){
                    columnStr.append(insertInfo.getItemName25()).append(",");
                    if("".equals(insertInfo.getItemValue25()) || insertInfo.getItemValue25() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue25()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName26()) ){
                    columnStr.append(insertInfo.getItemName26()).append(",");
                    if("".equals(insertInfo.getItemValue26()) || insertInfo.getItemValue26() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue26()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName27()) ){
                    columnStr.append(insertInfo.getItemName27()).append(",");
                    if("".equals(insertInfo.getItemValue27()) || insertInfo.getItemValue27() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue27()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName28()) ){
                    columnStr.append(insertInfo.getItemName28()).append(",");
                    if("".equals(insertInfo.getItemValue28()) || insertInfo.getItemValue28() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue28()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName29()) ){
                    columnStr.append(insertInfo.getItemName29()).append(",");
                    if("".equals(insertInfo.getItemValue29()) || insertInfo.getItemValue29() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue29()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName30()) ){
                    columnStr.append(insertInfo.getItemName30()).append(",");
                    if("".equals(insertInfo.getItemValue30()) || insertInfo.getItemValue30() == null ){
                        valueStr.append((String) null).append(",");
                    }else{
                        valueStr.append("'").append(insertInfo.getItemValue30()).append("'").append(",");
                    }
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName31()) ){
                    columnStr.append(insertInfo.getItemName31()+",");
                    valueStr.append("'").append(formatter.format(insertInfo.getItemValue31())).append("'").append(",");
                }
                if(StringUtils.isNotEmpty(insertInfo.getItemName32()) ){
                    columnStr.append(insertInfo.getItemName32()+",");
                    valueStr.append("'").append(formatter.format(insertInfo.getItemValue32())).append("'").append(",");
                }
                String columnFianlStr = columnStr.substring(0, columnStr.lastIndexOf(","));
                String valueFianlStr = valueStr.substring(0, valueStr.lastIndexOf(","));
                String insertSql = "insert into" + " " + insertInfo.getTableName()+"("+columnFianlStr+") values ("+ valueFianlStr+")";
                projectManageMapper.insertUpdateInfoToDb(insertSql);
            }
        }
        if(!CollectionUtils.isEmpty(deleteInfoList)){
            for (ProjectUpdateInfoVO deleteInfo : deleteInfoList) {
                String deleteSql = "delete from" + " " + deleteInfo.getTableName() + " " +"where "+" "+deleteInfo.getPrimaryKey() +"="+deleteInfo.getBusinessId();
                projectManageMapper.deleteInfoToDb(deleteSql);
            }
        }
    }

    @Override
    public void updateProjectAfterPass(SalesProjectManageVO projectManageVO, String token) {
      // 将修改后的数据放入redis缓存
        Map<String,Object> projectInfoMap = new HashMap<>();
        projectInfoMap.put(projectManageVO.getProjectManageId().toString(),projectManageVO);
        feginService.setCacheInfo(Constants.CACHE_PROJECT+projectManageVO.getProjectManageId(),projectInfoMap,token);
    }

    @Override
    public SalesProjectManageVO queryProjectByIDFromCache(int projectID, String token) {
        String managerCacheKey = Constants.CACHE_PROJECT+projectID;
        ResponseAPI cacheInfo = feginService.getCacheInfo(managerCacheKey,String.valueOf(projectID), token);
        String jsonObject= JSON.toJSONString(cacheInfo.getResult());
        //将json转成需要的对象
        SalesProjectManageVO salesProjectManage = JSONObject.parseObject(jsonObject,SalesProjectManageVO.class);
        return salesProjectManage;
    }

    @Override
    public void saveUpdateInfoToDBTemp(List<ProjectUpdateInfoVO> projectUpdateInfoVOs, String token) {
        if(!CollectionUtils.isEmpty(projectUpdateInfoVOs)){
            // 将上次保存的修改数据清空
            projectManageMapper.deleteUpdateInfo(projectUpdateInfoVOs.get(0));
            Map<String,List <ProjectUpdateInfoVO>> updateInfosMap = projectUpdateInfoVOs.stream().collect(Collectors.groupingBy(ProjectUpdateInfoVO::getOperateType));
            List<ProjectUpdateInfoVO> updateInfoList = updateInfosMap.get("update");
            List<ProjectUpdateInfoVO> insertInfoList = updateInfosMap.get("insert");
            List<ProjectUpdateInfoVO> deleteInfoList = updateInfosMap.get("delete");
            if(!CollectionUtils.isEmpty(updateInfoList)){
                projectManageMapper.saveUpdateInfoToDB(null,updateInfoList);
            }
            if(!CollectionUtils.isEmpty(insertInfoList)){
                projectManageMapper.saveUpdateInfoToDB(null,insertInfoList);
            }
            if(!CollectionUtils.isEmpty(deleteInfoList)){
                projectManageMapper.saveUpdateInfoToDB(null,deleteInfoList);
            }
        }


    }

    @Override
    public void updateStatusAfterSubmit(Integer businessId, Integer projectId, String token) {
        projectManageMapper.updateStatusAfterSubmit(businessId,projectId);
    }

    @Override
    public List<PurchaseOrderVO> queryPaymentPlanFromCache(List<PurchaseOrderVO> purchaseOrderVOs, String token) {
        if(!CollectionUtils.isEmpty(purchaseOrderVOs)){
            for (PurchaseOrderVO purchaseOrderVO : purchaseOrderVOs) {
                PurchaseOrderVO vo = PurchaseOrdeServiceImpl.queryPurchaseOrdeFromCache(purchaseOrderVO.getPurchaseId(), token);
                if(vo!=null){
                    purchaseOrderVO.setPaymentPlans(vo.getPaymentPlans());
                }
            }
        }
        return purchaseOrderVOs;
    }

    @Override
    public void deleteUpdateInfoByProjectId(Integer projectId, String token) {
        // 清空本次修改缓存内容
        deleteCacheInfo(projectId, token);
        // 清空日志表本次修改内容
        ProjectUpdateInfoVO projectUpdate = new ProjectUpdateInfoVO();
        projectUpdate.setProjectManageId(projectId);
        projectManageMapper.deleteUpdateInfo(projectUpdate);

    }

    private void deleteCacheInfo(Integer projectId, String token) {
        List<ProjectUpdateInfoVO> noSubmitUpdateInfoList = projectManageMapper.queryUpdateInfoNoSubmit(projectId);
        List<ProjectUpdateInfoVO> projectUpdateInfoList = noSubmitUpdateInfoList.stream().filter(item -> item.getProjectMId() != null).collect(Collectors.toList());
        List<ProjectUpdateInfoVO> contractUpdateInfoList = noSubmitUpdateInfoList.stream().filter(item -> item.getCmId() != null).collect(Collectors.toList());
        List<ProjectUpdateInfoVO> purchaseUpdateInfoList = noSubmitUpdateInfoList.stream().filter(item -> item.getPmId() != null).collect(Collectors.toList());
        List<ProjectUpdateInfoVO> receiptRecordUpdateInfoList = noSubmitUpdateInfoList.stream().filter(item -> item.getRrId() != null).collect(Collectors.toList());
        List<ProjectUpdateInfoVO> payApplyInfoList = noSubmitUpdateInfoList.stream().filter(item -> item.getPrId() != null).collect(Collectors.toList());
        List<ProjectUpdateInfoVO> billingApplyUpdateInfoList = noSubmitUpdateInfoList.stream().filter(item -> item.getBaId() != null).collect(Collectors.toList());
        List<ProjectUpdateInfoVO> billingRecordUpdateInfoList = noSubmitUpdateInfoList.stream().filter(item -> item.getBrId() != null).collect(Collectors.toList());
        List<ProjectUpdateInfoVO> backMoneyRecordUpdateInfoList = noSubmitUpdateInfoList.stream().filter(item -> item.getBmrId()!= null).collect(Collectors.toList());
        for (ProjectUpdateInfoVO projectUpdateInfoVO : projectUpdateInfoList) {
            feginService.deleteCacheInfo(Constants.CACHE_PROJECT+projectUpdateInfoVO.getProjectMId(), token);
        }
        for (ProjectUpdateInfoVO contractUpdateInfo : contractUpdateInfoList) {
            feginService.deleteCacheInfo(Constants.CACHE_CONTRACTINFO+contractUpdateInfo.getCmId(), token);
        }
        for (ProjectUpdateInfoVO purchaseUpdateInfo : purchaseUpdateInfoList) {
            feginService.deleteCacheInfo(Constants.CACHE_PURCHASEORDER+purchaseUpdateInfo.getPmId(), token);
        }
        for (ProjectUpdateInfoVO receiptRecordInfo : receiptRecordUpdateInfoList) {
            feginService.deleteCacheInfo(Constants.CACHE_RECEIPTRECORDS+receiptRecordInfo.getRrId(), token);
        }
        for (ProjectUpdateInfoVO payApplyInfo : payApplyInfoList) {
            feginService.deleteCacheInfo(Constants.CACHE_PAYREQUEST+payApplyInfo.getPrId(), token);
        }
        for (ProjectUpdateInfoVO billingApplyInfo : billingApplyUpdateInfoList) {
            feginService.deleteCacheInfo(Constants.CACHE_BILLINGRECORD+billingApplyInfo.getBaId(), token);
        }
        for (ProjectUpdateInfoVO billingRecordInfo : billingRecordUpdateInfoList) {
            feginService.deleteCacheInfo(Constants.CACHE_BILLINGRECORD+billingRecordInfo.getBrId(), token);
        }
        for (ProjectUpdateInfoVO backMoneyRecordInfo : backMoneyRecordUpdateInfoList) {
            feginService.deleteCacheInfo(Constants.CACHE_BACKMONEYRECORD+backMoneyRecordInfo.getBmrId(), token);
        }
    }

    @Override
    public List<ProjectUpdateInfoVO> queryUpdateInfoListBySearch(ProjectUpdateInfoVO projectUpdateInfoVO, String token) {
        return projectManageMapper.queryUpdateInfoListBySearch(projectUpdateInfoVO);
    }

    @Override
    public PageUtil<SalesProjectManageVO> queryUpdateProject(IPage<SalesProjectManageVO> page, SalesProjectManageVO projectManageVO, List<SysUserEntity> userList, String token) {
        if (projectManageVO.getOrderByProp() != null) {
            projectManageVO.setOrderByProp(StringUtils.camelToUnderline(projectManageVO.getOrderByProp()));
        }
        IPage<SalesProjectManageVO> iPage = projectManageMapper.queryUpdateProject(page, projectManageVO, userList);
        return new PageUtil<>(iPage);
    }

    @Override
    public Integer queryApproveIdByManagerId(Integer projectId, String token) {
        if(projectId!=null){
            return projectManageMapper.queryApproveIdByManagerId(projectId);
        }
        return null;
    }

    /**项目终验变初验的处理
     * true表示通过，已更改状态信息；false代表失败
     * @param projectManageVO
     * @param token
     * @return
     */
    @Override
    public Boolean projectStateUpdate(SalesProjectManageVO projectManageVO, String token) {
        SalesProjectManageVO manageVO = projectManageMapper.selectByPrimaryKey(projectManageVO.getProjectManageId());
        if (manageVO.getBusinessId().describeConstable().isEmpty()) {
           return false;
        }
        ApprovalVO approval = approvalService.queryApprovalByAppID(manageVO.getBusinessId());
        //1.生成日志
        approvalService.insertApprovalLog(approval.getApprovalId(),"撤回","","");
        //2.修改审批状态为撤回
        approvalMapper.approvalWithdrawal(approval.getBusinessId(),approval.getApprovalId());
        //3.修改项目状态为初验
        manageVO.setProjectState(5);
        projectManageMapper.updateByPrimaryKeySelective(manageVO);
        return true;
    }

    // 项目变更审批通过时将变更详情列表最后更新时间同步
    private void updateLastTimeAfterApprove(Integer projectManageId) {
        projectManageMapper.updateLastTimeAfterApprove(projectManageId);
    }



    private void deleteUpdateInfoAfterRejection(Integer projectManageId){
        projectManageMapper.deleteUpdateInfoAfterRejection(projectManageId);
    }


    public void rjSendEmailAndPushNotice(SalesProjectManageVO projectManageVO,String token){
        //SalesProjectManageVO vo = projectManageMapper.selectByPrimaryKey(projectManageVO.getProjectManageId());
//        if (vo.getAuditOpinion() == null || vo.getAuditOpinion().isEmpty()){
//            vo.setAuditOpinion("无");
//        }
        //获取人员信息
        // ResponseAPI<SysUserEntity> res = feginService.searchUserInfoByIds(supplier.getCreator(),token);
        //SysUserEntity user = res.getResult();
        //EnterpriseVO enterpriseVO = enterpriseMapper.selectEnterprise(supplier.getEnterpriseId());
        //发送邮件
        String titel = "【系统通知】供应商信息 - 流程单审批驳回通知";
//        String msg = "<div>"
//                + "<p> 尊敬的" + user.getLoginName() + " ：<br></p ></div>"
//                + "<p> &nbsp; &nbsp; &nbsp; 您好，您提交的供应商信息已被驳回：</p>"
//                + "<p> &nbsp; &nbsp; &nbsp; 供应商名称："+enterpriseVO.getEnterpriseName()+"<p>"
//                + "<p> &nbsp; &nbsp; &nbsp; 联系人："+supplier.getSupplierContacts()+"<p>"
//                + "<p> &nbsp; &nbsp; &nbsp; 审批人："+AuthUtils.getUserName()  + " / " + AuthUtils.getUserAccount() + "<p>"
//                + "<p> &nbsp; &nbsp; &nbsp; 审批时间："+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())+ "<p>"
//                + "<p> &nbsp; &nbsp; &nbsp; 审批意见："+vo.getAuditOpinion()+"<p>"
//                + "<p> &nbsp; &nbsp; &nbsp; 系统查看路径：客户关系管理系统 - 供应商信息管理 - 供应商信息 " +
//                "<a href='"+webSitUrl+"/?m=crm&p=supplier&me=supplierInfo'>进入</a></p>"
//                + "<div><p style='text-indent: 2em'>谢谢！</p>"
//                + "<p> &nbsp; &nbsp; &nbsp; 说明：该邮件为系统自动发送，请勿回复。<p>";
        //获取抄送
        // StringBuilder emailList = selectCC();
        CompletableFuture.runAsync(() -> EmailUtils.sentMailByAddressee(null,null,titel,null,token));
        //调用通知接口
        CompletableFuture.runAsync(() -> NoticUtils.pushNotic(projectManageVO.getApprovalId(),  new Timestamp(System.currentTimeMillis()), projectManageVO.getCreator(),
                Constants.WORK_STATE_STOP,Constants.UPDATE_MANAGER_TYPE,0,token));
    }




    public void sendEmailAndPushNotice(SysUserEntity users,SalesProjectManageVO projectManageVO,String token){
        // SupplierVO vo = supplierMapper.selectSupplierById(supplier.getSupplierId());
//        EnterpriseVO enterpriseVO = enterpriseMapper.selectEnterprise(supplier.getEnterpriseId());
//        SysUserEntity creatorInfo = feginService.searchUserInfoById(supplier.getCreator(), token).getResult();
        //发送邮件
//        String titel = "【系统通知】供应商信息 - 流程单审批通知";
//        String msg = "<div>"
//                + "<p> 尊敬的" + users.getLoginName() + " ：<br></p ></div>"
//                + "<p> &nbsp; &nbsp; &nbsp; 您好，您有一张新的供应商信息审批需要处理：</p>"
//                + "<p> &nbsp; &nbsp; &nbsp; 供应商名称："+enterpriseVO.getEnterpriseName()+"<p>"
//                + "<p> &nbsp; &nbsp; &nbsp; 联系人："+vo.getSupplierContacts()+"<p>"
//                + "<p> &nbsp; &nbsp; &nbsp; 申请人："+creatorInfo.getLoginName()  + " / " + creatorInfo.getAccount() + "<p>"
//                + "<p> &nbsp; &nbsp; &nbsp; 申请时间："+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "<p>"
//                + "<p> &nbsp; &nbsp; &nbsp; 系统审批路径：客户关系管理系统 - 待办事项 - 待办审批 " +
//                "<a href='"+webSitUrl+"/?m=crm&p=todoItems&me=todoApproval'>进入</a></p>"
//                + "<p> &nbsp; &nbsp; &nbsp; APP审批路径：工作台 - 待办审批 - CRM系统</p>"
//                + "<div><p style='text-indent: 2em'>谢谢！</p>"
//                + "<p> &nbsp; &nbsp; &nbsp; 说明：该邮件为系统自动发送，请勿回复。<p>";
//        StringBuilder emailList = selectCC();
//        CompletableFuture.runAsync(() -> EmailUtils.sentMailByAddressee(users.getEmail(),null,titel,msg,token));
        //调用通知接口
        CompletableFuture.runAsync(() -> NoticUtils.pushNotic(projectManageVO.getApprovalId(),  new Timestamp(System.currentTimeMillis()), projectManageVO.getCreator(),
                Constants.WORK_STATE_START,Constants.UPDATE_MANAGER_TYPE,users.getUserId(),token));
    }

    @Override
    public void exportProjectInfo(HttpServletResponse response, List<SalesProjectManageVO> list, String token) throws Exception {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        List<String> statesList = new ArrayList<>();
        statesList.add("projectState");
        statesList.add("projectApprovalState");
        statesList.add("projectApprovalStateOne");
        JSONObject userObject = feginService.getUserInfo(token);
        JSONObject jsonObject = feginService.queryDictionaryLookupInfo("crm", statesList);
        List<String> classfiedCode = new ArrayList<>();
        classfiedCode.add("projectStage");
        classfiedCode.add("projectType");
        classfiedCode.add("projectClasses");
        classfiedCode.add("projectDifferentId");
        Map<String, List<DictionaryLookupItemVO>> listMap = dictionaryService.queryDictionaryLookupInfo(1, classfiedCode);
        for (int i = 0; i < list.size(); i++) {
            SalesProjectManageVO pmVO = list.get(i);
            pmVO.setProjectManageId(i+1);
            pmVO.setProjectTypeName((String)getCRMDictionaryNameByCode("projectType",listMap).get(pmVO.getProjectType() + ""));
            pmVO.setProjectClassesName((String)getCRMDictionaryNameByCode("projectClasses",listMap).get(pmVO.getProjectClasses() + ""));
            pmVO.setProjectPrincipalName((String)getUserNameById(userObject).get(pmVO.getProjectPrincipal()));
            pmVO.setProjectStateName((String) getDictionaryNameByCode("projectState", jsonObject).get(pmVO.getProjectState() + ""));
            pmVO.setProjectDifferentName((String)getCRMDictionaryNameByCode("projectDifferentId",listMap).get(pmVO.getProjectDifferentId() + ""));
            pmVO.setProjectExpectMoneyValue(new DecimalFormat("0.00").format(Double.parseDouble(pmVO.getProjectExpectMoney())));
            pmVO.setProjectManageMoneyValue(new DecimalFormat("0.00").format(Double.parseDouble(pmVO.getProjectManageMoney() == null ? "0" : pmVO.getProjectManageMoney().getValue())));
            pmVO.setStageStateName((String)getCRMDictionaryNameByCode("projectStage",listMap).get(pmVO.getStageStateId() + ""));
            pmVO.setAuditStateName((String)getDictionaryNameByCode("projectApprovalState",jsonObject).get(pmVO.getAuditState() + ""));
            pmVO.setApproveStateName((String)getDictionaryNameByCode("projectApprovalStateOne",jsonObject).get(pmVO.getApproveState() + ""));
            pmVO.setReturnedMoney(new DecimalFormat("0.00").format(Double.parseDouble(pmVO.getReturnedMoney())));
            pmVO.setInvoicedMoney(new DecimalFormat("0.00").format(Double.parseDouble(pmVO.getInvoicedMoney())));
            pmVO.setPaymentedMoney(new DecimalFormat("0.00").format(Double.parseDouble(pmVO.getPaymentedMoney())));
            pmVO.setCollectTicketedMoney(new DecimalFormat("0.00").format(Double.parseDouble(pmVO.getCollectTicketedMoney())));
        }
        //获取yml模板位置
        YamlPropertiesFactoryBean factoryBean = new YamlPropertiesFactoryBean();
        String path = "application.yml";
        factoryBean.setResources(new ClassPathResource(path));
        Properties properties = factoryBean.getObject();
        String templatePath = String.valueOf(properties.get("report.projectTemplate"));
        //依据根目录获取模板位置
        TemplateExportParams params = new TemplateExportParams(templatePath);
        Map<String, Object> map = new HashMap<>();
        map.put("projectInfo",list);
        ReportUtils.exportExcel(params,map,"项目信息",response);
    }

    @Override
    public SalesProjectManageVO queryProjectByPurchaseId(Integer id) {
        PurchaseOrderVO purchaseOrderVO = purchaseOrdeService.getPurchaseOrdeInfoById(id);
        return projectManageMapper.selectByPrimaryKey(purchaseOrderVO.getProjectManageId());
    }

    @Override
    public SysUserEntity queryProjectHeadByProjectId(Integer projectID,String token){
        Integer projectPrincipalId = projectManageMapper.queryProjectHeadByProjectId(projectID);
        ResponseAPI<SysUserEntity> responseAPI = feginService.searchUserInfoById(projectPrincipalId, token);
        return responseAPI.getResult();
    }

    @Override
    public int transforPrincipal(Integer userId, List<SalesProjectManageVO> voList, String token) {
        if (!voList.isEmpty()) {
            return projectManageMapper.transforPrincipal(userId, voList);
        }
        return 0;
    }

    public void projectApprovalOneWithdrawal(ApprovalVO approval,String token) {
        SalesAuditVO auditVO = auditMapper.queryAuditByWorkId(approval.getApprovalId());
        SalesProjectManageVO projectManageVO = this.queryProjectInfoById(auditVO.getSalesRelationId(),token);
//        projectManageVO.setApproveState(auditVO.getAuditState());
//        projectManageVO.setProcessComments(auditVO.getProcessComments());
//        projectManageVO.setReasonApplicationOne(auditVO.getReasonApplication());
        //删除之前免审的迁移记录
        auditMapper.deleteByRelationId(projectManageVO.getProjectOpportunityId(), Constants.COST_MODEL_ID);
        //更改机会状态
        SalesOpportunityVO opportunityVO = opportunityMapper.selectByPrimaryKey(projectManageVO.getProjectOpportunityId());
        approvalService.insertApprovalLog(opportunityVO.getBusinessId(),"撤回",
                "",approval.getOpinion());
        approvalMapper.approvalWithdrawal(null,opportunityVO.getBusinessId());
        opportunityMapper.updateByPrimaryKeySelective(opportunityVO);
        auditMapper.updateByPrimaryKeySelective(auditVO);
    }

    public void projectApprovalWithdrawal(ApprovalVO approval,String token) {
        SalesProjectManageVO projectManageVO = projectManageMapper.queryProjectApprovalByWorkId(approval.getApprovalId());
        projectManageVO.setProjectState(5);
        projectManageMapper.updateByPrimaryKeySelective(projectManageVO);
    }

    public List<SalesProjectManageVO> queryAllProjectsByUser(String token){
        List<SysUserEntity> userList = projectMemberService.queryUserList(AuthUtils.getUserId(), Constants.OPPORTUNITY_MODEL_NAME, token);
        return projectManageMapper.queryAllProjectsByUser(userList);
    }

    public List<SalesProjectManageVO> queryAllProjects() {
        return projectManageMapper.queryAllProjects();
    }
}
